C 11 extern模板:我们在哪里真正需要它们?
在C03中,我们具有模板显式实例化定义(模板类Foo< int>),其强制模板类的实例化.
在C 11中,我们有模板显式实例化声明(extern模板类Foo< int>),它应该阻止模板类的隐式实例化. (Class template instantiation) 我试图模拟我实际需要显式实例化声明的情况,以减少编译时间.但我不能.看起来一切都没有这个功能(或不能使用它). 这是一个例子: //Foo.h #pragma once template<class T> class Foo { T inst; public: Foo(T i); T& get() const; }; //Foo.cpp #include "stdafx.h" #include "Foo.h" template<class T> Foo<T>::Foo(T inst) : inst(inst) { } template<class T> T& Foo<T>::get() const { return inst; } template class Foo<int>; //explicit instantiation definition //test1.h #pragma once #include "Foo.h" //This line does not work //extern template class Foo<int>; //explicit instantiation declaration. void baz(); //test1.cpp #include "stdafx.h" #include "test1.h" void baz() { Foo<int> foo(10); int i = foo.get(); } 结果不取决于我是否评论(extern模板类Foo< int> ;;)行. 这是* .obj文件的符号:
注意在test1.obj中标记为UNDEF的Foo< int> :: Foo< int>(int)和int Foo< int> :: get(void)const这意味着它们必须在别处解析(即Foo仅被编译)一旦). ATTEMP#2: 如果我在Foo.h文件中定义完整模板(没有显式实例化定义),那么extern模板没有帮助 – 模板编译两次(在test1.cpp和test2.cpp中). 例: //test1.h #pragma once #include "Foo.h" void baz(); //test1.cpp #include "stdafx.h" #include "test1.h" void baz() { Foo<int> foo(10); //implicit instantiation of Foo<int> int i = foo.get(); } //test2.h #pragma once #include "Foo.h" extern template class Foo<int>; void bar(); //test2.cpp #include "stdafx.h" #include "test2.h" void bar() { Foo<int> foo(10); //should refer to Foo<int> from test1.obj but IT IS NOT int i = foo.get(); } 这是符号转储:
在两个* .obj文件中,Foo呈现. 所以我的问题是显式实例化声明可能有用吗?或者我可能会在测试中遗漏一些东西? 我用的是VS2013编译器. 解决方法
这是一个很好的解释为什么ATTEMP#2不能按我的意愿工作:
Is there a bug with extern template in Visual C++? 简而言之,当您在头文件中定义和实现模板时,编译器可能会内联它.然后它通过标准(14.7.2 / 10“显式实例化”)使显式实例化定义不起作用. 所以我们需要强制编译器不内联模板.例如,在声明之后实现它. template<class T> class Foo { ... T get() const; }; template<class T> T Foo<T>::get() const { ... } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |