gpt4 book ai didi

c++ - 使用不完整类型参数化的模板的外部模板

转载 作者:可可西里 更新时间:2023-11-01 17:54:19 29 4
gpt4 key购买 nike

一个可编译的例子:

main.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 在模板实例化时应该是可见的。为什么?

编辑:修复了示例中的拼写错误。

最佳答案

实例化声明的效果,即保证模板不被隐式实例化,不适用于inline根据 14.7.2 [temp.explicit] 第 10 段的功能:

Except for inline functions, declarations with types deduced from their initializer or return value (7.1.6.4), const variables of literal types, variables of reference types, and class template specializations, explicit instantiation declarations have the effect of suppressing the implicit instantiation of the entity to which they refer. [ Note: The intent is that an inline function that is the subject of an explicit instantiation declaration will still be implicitly instantiated when odr-used (3.2) so that the body can be considered for inlining, but that no out-of-line copy of the inline function would be generated in the translation unit.—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;
}

关于c++ - 使用不完整类型参数化的模板的外部模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27609522/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com