pet*_*sev 1 c++ linker gcc templates
我正在寻找GCC与MSVC不同的概述或描述,用于编译+链接具有特化的模板类.例如,这种类型的东西适用于GCC但不适用于MSVC:
// Base.h
template <typename T> struct Base {
template <class G> QString makeTitle(const G* obj){obj->CompilerError();}
};
// in Foo.cpp
template <> template <class G> QString Base<T_1>::makeTitle(const G* obj) { return mystr(); }
void SomeFunc() {
std::cout<< Base<T_1>().makeTitle<myclass>() ;
}
Run Code Online (Sandbox Code Playgroud)
并且解决方案往往是我必须在使用之前在Base.h中声明特化,或者在Windows上存在链接错误.MSVC如何/为什么隐式地实例化,以及GCC如何/为什么对某些cpp文件中声明的特化是健壮的?
相关问题,注意一般'使用前声明'要求: 模板专业化 - MSVC和GCC/MinGW之间的不同行为
第一件事是如果任何翻译单元包含标题并导致特化的定义而编译器没有看到声明,那么您的代码违反了ODR规则.由于这是未定义的行为,因此一个编译器接受它而另一个拒绝它的事实在合理范围内.
正如您已经想到的那样,正确的代码是提供特化的声明,并且可以在任何编译器中使用.
至于为什么它似乎工作,甚至为什么它实际上在gcc中工作,这很可能是代码生成方式和链接器处理目标文件的问题.特别是在gcc中,编译器将在需要它的转换单元中生成特化(并且看不到您自己的特化),但它将被标记为弱符号.如果除了[最多]一个定义之外的所有定义都很弱,gcc链接器将接受一个被多重定义的符号,在最终的可执行文件中保留强符号.