-
It's not just VC++. Comeau online gives the following output:
Code:
Thank you for testing your code with Comeau C/C++!
Tell others about http://www.comeaucomputing.com/tryitout !
Your Comeau C/C++ test results are as follows:
Comeau C/C++ 4.3.9 (Mar 27 2007 17:24:47) for ONLINE_EVALUATION_BETA1
Copyright 1988-2007 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions
"ComeauTest.c", line 5: warning: variable "i" is used before its value is set
int i = i + 0;
^
In strict mode, with -tused, Compile succeeded (but remember, the Comeau online compiler does not link).
Compiled with C++0x extensions enabled.
I don't feel like checking the standard at the moment. I'd imagine you'd have to combine several parts to come to a conclusion.
-
Having the smart pointer code embedded in both my DLL and my main app, it seems that TWO objects are created and the static members, the map and lock, are not the same across the DLL boundaries.
I'm guess I'm going to have to imbed it into the DLL and export the class to the app.
EDIT:
As usual, when I try to export the class, I get linking errors instead:
Code:
template<typename T> class AFX_EXT_CLASS CMemoryManager;
2>Do X For Every FileDlg.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall CMemoryManager<class std::vector<class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >,class std::allocator<class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > > > >::~CMemoryManager<class std::vector<class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >,class std::allocator<class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > > > >(void)" referenced in function "public: void __thiscall CDoXForEveryFileDlg::OnBnClickedBrowseapp(void)"
I was also unable to map these into definitions in the .cpp file:
Code:
template<typename NewT> operator CMemoryManager<NewT>& () const;
template<typename T2> static CMemoryManager<T> MemoryManagerNew(T2* pNew) throw(...);
CMemoryManagerTimeCritical& operator = (T* p) throw(...) { CMemoryManager<T>::operator = (p); return *this; }
CMemoryManagerTimeCritical& operator = (CMemoryManagerTimeCritical<T>& r) throw(...);
//template<typename T, typename T2> CMemoryManager<T> CMemoryManager<T>::MemoryManagerNew(T2* pNew) throw(...)
//{
// MM_RETHROW_ERRORS_START;
// CMemoryManager<T> mm;
// T* pLocal = pNew;
// mm.Attach(pLocal);
// return mm;
// MM_RETHROW_ERRORS_END("CMemoryManager::MemoryManagerNew(T* pNew)");
//}
//template<typename T, typename NewT> CMemoryManager<T>::operator CMemoryManager<NewT>& () const
//{
// NewT* pTo = dynamic_cast<NewT*>(p); // Security cast to make sure the new type in compatible with the old
// ASSERT(pTo);
// return *(CMemoryManager<NewT>*)this;
//}
//MMC_TWO(CMemoryManagerTimeCritical<T>&)
//template<typename T, typename T2> CMemoryManagerTimeCritical<T>& CMemoryManagerTimeCritical<T>::operator = (T2* p) throw(...)
//{
// CMemoryManager<T>::operator = (p);
// return *this;
//}
//template<typename T, typename T2> CMemoryManagerTimeCritical<T>& CMemoryManagerTimeCritical<T>::operator = (CMemoryManagerTimeCritical<T2>& r) throw(...)
//{
// CMemoryManager<T>::operator = (r);
// return *this;
//}
#define MMTC_TWO(return_type) template<typename T, typename T2> return_type CMemoryManagerTimeCritical<T>
Any ideas or suggestions?
-
You can't put a template in a DLL.
Edit: Clarifying: you can't export a template from a DLL. Except by using the compiler's extern template extension, for a given set of instantiations. But not the generic code.
-
Yes, I figured, so I need another solution to this.
So here's another problem:
Code:
CMemoryManager(const CMemoryManager<T>& rmm)
Can also take a class of type CMemoryManagerTimeCritical or any other class derived from it, which it should not, because they're not compatible.
I was able to block such an attempt by making a prive constructor that takes the specified types.
Creating a static variable in a different thread than the main will cause the object to be destructed on the main thread rather than the thread that created it. In Release mode, I also get an access violation due to freeing an invalid address. This may be a problem. It may be that static vars are dangerous?