外部模板,用于使用非竞争类型参数化的模板
Extern template for template parametrized with incompete type
一个可编译的例子:
主.cpp
#include "test.h"
int main(int argc, char* argv[]) {
auto myPtr = std::unique_ptr<MyClass>(getMyPtr());
}
测试.h
#ifndef TEST_H
#define TEST_H
#include <memory>
class MyClass;
extern template class std::unique_ptr<MyClass>;
MyClass* getMyPtr();
#endif
测试.cpp
#include "test.h"
class MyClass {};
template class std::unique_ptr<MyClass>;
MyClass* getMyPtr() { return new MyClass; }
G++ 4.9.2 投诉
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,
^
即使 MyClass 在模板实例化时应该是可见的。为什么?
编辑:修复了示例中的拼写错误。
根据 14.7.2 [temp.explicit] 第 10 段,实例化声明的效果(即保证模板未隐式实例化(不适用于inline
函数:
除了内联函数、类型从其初始值设定项或返回值 (7.1.6.4( 推导的声明、文本类型的 const 变量、引用类型的变量和类模板专用化之外,显式实例化声明具有抑制它们所引用的实体的隐式实例化的效果。[注意:目的是作为显式实例化声明主题的内联函数在 odr 使用 (3.2( 时仍将隐式实例化,以便可以考虑内联主体,但不会在翻译单元中生成内联函数的外联副本。
标准库显然可以自由地将其任何功能声明为 inline
。也就是说,使用实例化声明不会影响对使用标准库模板类定义的类型的要求(当然,除非另有指定(。GCC 在此类模板的定义中定义了 std::unique_ptr<...>
的析构函数,使其隐式内联。下面是一个演示问题的示例源:根据是否定义了DECL_ONY
编译器:
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;
}
相关文章:
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 如何解决一元"*"(有"字符")错误的无效类型参数?
- "std::shared_ptr":不是参数"_Ty"的有效模板类型参数
- 具有可变参数非类型参数的模板专用化
- 函数类型参数的模板参数推导
- PowerShell 使用结构类型参数调用 C++ DLL 的导出函数
- 对于非常量指针类型的参数,未调用具有常量指针模板类型参数的功能
- 为模板传递非类型参数 agument
- 为什么带有类型参数的运算符 () 可以应用于 result_of 上下文中的类型?
- 使用其他模板类型参数作为要在函数签名中使用的类型别名声明
- 如何避免具有相同类型参数的函数中的错误
- 将内置类型变量传递给只有一个类类型参数的"+"运算符函数时自动类型转换的构造函数
- c++非类型参数包扩展
- 如何实现对参数顺序不可知的std::same_as的广义形式(即对于两个以上的类型参数)
- 在不同的模板参数包之间分发非类型参数包
- 如何在使用容器和字符串时强制使用显式分配器类型参数
- 错误:一元"*"的类型参数无效(具有"int"):使用 mergesort 计算
- EXPECT_CALL具有 unique_ptr 引用类型参数的模拟函数
- 作为模板类型参数,为什么 type[N] 与其专用版本不匹配----模板<类 T>类 S<T[]>
- 外部模板,用于使用非竞争类型参数化的模板