C++ 模板对象文件链接-与clang和gcc的不同行为

C++ 模板对象文件链接-与clang和gcc的不同行为,c++,templates,gcc,linker,clang,C++,Templates,Gcc,Linker,Clang,关于gcc和clang之间的不同行为有很多问题。然而,我还没有找到解决我问题的办法 我使用模板,我想传播类的定义和实现。我读了很多关于它的书,我意识到了不同的可能性。我选择要支持的特定声明模板。与: template class Temp<char>; template class Temp<double>; 显式模板实例化属于“.cc”实现文件,而不是标头。如果要在标题中声明,可以使用extern: extern template class Temp&l

关于gcc和clang之间的不同行为有很多问题。然而,我还没有找到解决我问题的办法

我使用模板,我想传播类的定义和实现。我读了很多关于它的书,我意识到了不同的可能性。我选择要支持的特定声明模板。与:

   template class Temp<char>;
   template class Temp<double>;

显式模板实例化属于“.cc”实现文件,而不是标头。如果要在标题中声明,可以使用
extern

extern template class Temp<char>;
extern template class Temp<double>;
extern模板类Temp;
外部模板类Temp;
这将避免使用多定义的符号,否则您可能会遇到叮当声


<> P>可能是GCC支持头文件中的显式实例化,但这并不意味着它是正确的C++,只是GCC在这种情况下是自由的。不要依赖于此。

显式模板实例化属于“.cc”实现文件,而不是标题。如果要在标题中声明,可以使用
extern

extern template class Temp<char>;
extern template class Temp<double>;
extern模板类Temp;
外部模板类Temp;
这将避免使用多定义的符号,否则您可能会遇到叮当声


<> P>可能是GCC支持头文件中的显式实例化,但这并不意味着它是正确的C++,只是GCC在这种情况下是自由的。不要依赖于此。

函数模板的显式实例化是一个定义。类模板的显式实例化是实例化类模板的所有[non-template]成员函数的简称。在C++中有一个实体的多个定义会导致违反ODR规则(一个定义规则)。不需要诊断违反ODR规则的情况

因此,模板的显式实例化属于一个“.cc”文件。如果要声明模板将在某个翻译单元中显式实例化,可以使用
extern
模板声明,例如:

template <typename> void f();
template <typename> class F { /*...*/ };

extern template void f<int>();
extern template class F<int>();
模板void f();
模板类F{/*…*/};
外部模板void f();
外部模板类F();

extern
模板声明允许在头中定义模板,但禁止隐式实例化。相反,
extern
模板声明承诺将有一个翻译单元提供显式实例化。

函数模板的显式实例化是一个定义。类模板的显式实例化是实例化类模板的所有[non-template]成员函数的简称。在C++中有一个实体的多个定义会导致违反ODR规则(一个定义规则)。不需要诊断违反ODR规则的情况

因此,模板的显式实例化属于一个“.cc”文件。如果要声明模板将在某个翻译单元中显式实例化,可以使用
extern
模板声明,例如:

template <typename> void f();
template <typename> class F { /*...*/ };

extern template void f<int>();
extern template class F<int>();
模板void f();
模板类F{/*…*/};
外部模板void f();
外部模板类F();
extern
模板声明允许在头中定义模板,但禁止隐式实例化。相反,
extern
模板声明承诺将有一个翻译单元提供显式实例化

extern template class Temp<char>;
extern template class Temp<double>;
template <typename> void f();
template <typename> class F { /*...*/ };

extern template void f<int>();
extern template class F<int>();