为什么'extern template class'技术没有按预期工作?



原来的问题已经完善

给定一个名为main.cpp的源代码文件如下:

#include <string>
extern template class std::basic_string<char>;
template<typename T>
struct A
{
T n = {};
T get() const
{
return n;
}
};
extern template struct A<int>;
int main()
{
auto a = A<int>{}.get(); // undefined reference to `A<int>::get() const'
auto b = static_cast<int>(std::string{}.size()); // ok
return a + b;
}

我所期望的:

请注意,源代码具有extern template class std::basic_string<char>,但没有template class std::basic_string<char>

因此,编译器不会实例化类std::basic_string<char>,那么g++ main.cpp会像在A<int>{}.get()上一样在std::string{}.size()上导致链接错误。

我观察到的情况:

std::string{}.size()线上的g++ main.cpp是可以的。在线演示

为什么extern template class技术不能按预期工作

它不起作用的原因至少有两个。

One不禁止实现将库类和函数模板实例化声明为extern template。CCD_ 12和CCD_。

$ g++ -E main.cpp | grep 'extern.*string'
extern template class basic_string<char>;      // <-- from the library
extern template class basic_string<wchar_t>;   // <-- from the library
extern template class std::basic_string<char>; // <-- your line

标准库实现包含显式实例化定义(您可以挖掘源代码(。

Two一个实体是显式实例化声明的主体,并且它的使用方式也会导致翻译单元中的隐式实例化,它应该是程序中某个地方的显式实例化定义的主体;否则程序格式错误,不需要诊断

NDR的一个可能的理由是extern template不应该阻止内联和其他不涉及链接的使用。事实上,使用-O2A::get是内联的,并且程序构建得很好。没有任何既定的技术会迫使这个项目无论如何都被拒绝。由于链接器错误,它可以被拒绝,但不要求出现链接器错误。

最新更新