Smi*_*les 8 c++ templates forward-declaration incomplete-type c++11
一个可编辑的例子:
main.cpp中
#include "test.h"
int main(int argc, char* argv[]) {
auto myPtr = std::unique_ptr<MyClass>(getMyPtr());
}
Run Code Online (Sandbox Code Playgroud)
test.h
#ifndef TEST_H
#define TEST_H
#include <memory>
class MyClass;
extern template class std::unique_ptr<MyClass>;
MyClass* getMyPtr();
#endif
Run Code Online (Sandbox Code Playgroud)
TEST.CPP
#include "test.h"
class MyClass {};
template class std::unique_ptr<MyClass>;
MyClass* getMyPtr() { return new MyClass; }
Run Code Online (Sandbox Code Playgroud)
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,
^
Run Code Online (Sandbox Code Playgroud)
即使MyClass在模板实例化时应该是可见的.为什么?
编辑: 在示例中修复了拼写错误.
实例化声明的效果,即模板未隐式实例化的保证,不适用于inline根据14.7.2 [temp.explicit]第10段的函数:
除了内联函数,从其初始值或返回值(7.1.6.4)推导出类型的声明,文字类型的常量变量,引用类型的变量和类模板特化之外,显式实例化声明具有抑制隐式实例化的效果.他们所指的实体.[注意:意图是当使用odr(3.2)时,仍然会隐式实例化作为显式实例化声明主题的内联函数,以便可以考虑使用内联体,但是不需要外联副本内联函数的内容将在翻译单元中生成.-end note]
标准库显然可以自由声明其任何功能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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
541 次 |
| 最近记录: |