External template for a template parameterized with incompetence type

Compiled Example:

main.cpp

#include "test.h" int main(int argc, char* argv[]) { auto myPtr = std::unique_ptr<MyClass>(getMyPtr()); } 

test.h

 #ifndef TEST_H #define TEST_H #include <memory> class MyClass; extern template class std::unique_ptr<MyClass>; MyClass* getMyPtr(); #endif 

test.cpp

 #include "test.h" class MyClass {}; template class std::unique_ptr<MyClass>; MyClass* getMyPtr() { return new MyClass; } 

g ++ 4.9.2 complains

 In file included from c:/devel/mingw32/i686-w64-mingw32/include/c++/memory:81:0, from main.cpp:4: c:/devel/mingw32/i686-w64-mingw32/include/c++/bits/unique_ptr.h: In instantiation of 'void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = MyClass]': c:/devel/mingw32/i686-w64-mingw32/include/c++/bits/unique_ptr.h:236:16: required from 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = MyClass; _Dp = std::default_delete<MyClass>]' main.cpp:64:53: required from here c:/devel/mingw32/i686-w64-mingw32/include/c++/bits/unique_ptr.h:74:22: error: invalid application of 'sizeof' to incomplete type 'MyClass' static_assert(sizeof(_Tp)>0, ^ 

although MyClass should be visible at the time the template is created. Why?

Edit: fixed a typo in the example.

+7
c ++ c ++ 11 templates forward-declaration incomplete-type
source share
1 answer

The effects of creation claims, i.e. the guarantee that the template is not created implicitly does not apply to inline functions in accordance with clause 14.7.2 [temp.explicit]:

With the exception of built-in declaration functions with types derived from their initializer or return value (7.1.6.4), literal type constant variables, reference type variables, and specialized template classes, explicit instance declarations have the effect of suppressing the implicit instance of the object to which they refer . [Note. The goal is that the built-in function that is the subject of the explicit declaration of instantiation will still be implicitly created using odr (3.2) so that the body can be considered for attachment, but this non-repixel copy of the built-in function will be generated in the translation block. -end note]

The standard library can explicitly declare any of its functions as inline . That is, the use of an instance declaration does not affect the requirement that types are defined by the standard class of the library template (unless otherwise specified, of course). gcc defines a destructor for std::unique_ptr<...> in the definition of this class template, which makes it implicitly inline. Here is an example source that demonstrates the problem: depending on whether it is DECL_ONY compiler or not:

 template <typename T> struct foo { ~foo() #ifdef DECL_ONLY ; #else { static_assert(sizeof(T), "defined!"); } #endif }; #ifdef DECL_ONLY template <typename T> foo<T>::~foo() { static_assert(sizeof(T), "defined!"); } #endif class MyClass; extern template struct foo<MyClass>; int main(int , char* []) { foo<MyClass> f; } 
+6
source share

All Articles