|
Boost : |
Subject: Re: [boost] [move] You can do it better: implementing push_back and handling implicit conversions
From: Stephan T. Lavavej (stl_at_[hidden])
Date: 2011-03-09 09:47:02
[Thomas Klimpel]
> Find attached a test case showing the scenario I described.
> This code actually really triggers the mentioned compile error.
> Standard wording can't help us here, because the standard doesn't
> say anything about dynamic link libraries. So I wouldn't see this
> as a bug, even if it is annoying at times.
By design.
C:\Temp>type meow.cpp
template <class T> struct container {
T m;
void forward_member_function() {
m.member_function();
}
};
struct b { };
#ifdef BOOM
struct __declspec(dllexport) my_class : public container<b> { };
#else
struct my_class : public container<b> { };
#endif
C:\Temp>cl /EHsc /nologo /W4 /c meow.cpp
meow.cpp
C:\Temp>cl /EHsc /nologo /W4 /c /DBOOM meow.cpp
meow.cpp
meow.cpp(5) : error C2039: 'member_function' : is not a member of 'b'
meow.cpp(9) : see declaration of 'b'
meow.cpp(4) : while compiling class template member function 'void container<T>::forward_member_function(void)'
with
[
T=b
]
meow.cpp(12) : see reference to class template instantiation 'container<T>' being compiled
with
[
T=b
]
http://msdn.microsoft.com/en-us/library/81h27t8c.aspx says:
"Inheritance and Exportable Classes
All base classes of an exportable class must be exportable."
http://msdn.microsoft.com/en-us/library/twa2aw10.aspx says:
"the compiler changed the semantics of dllexport when it is applied to a class that has one or more base-classes and when one or more of the base classes is a specialization of a class template. In this case, the compiler implicitly applies dllexport to the specializations of class templates."
(This page is a little confusing because it was written when VS 2003 was new.)
When my_class is dllexported, its base class container<b> is explicitly instantiated and compiled into the DLL. That's why container<b>::forward_member_function() is being instantiated and subsequently exploding.
I'm not an expert when it comes to DLLs, but I can't imagine another way for this to physically work.
In the absence of dllexport, the compiler plays by the Standard rules that allow std::list<T> to work when T doesn't have op<(), as long as std::list<T>::sort() isn't called.
Stephan T. Lavavej
Visual C++ Libraries Developer
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk