考虑以下最小例子:
template <int A> struct Foo {
inline Foo();
};
template <> struct Foo<1> {
inline Foo();
};
template <int A>
inline Foo<A>::Foo() {}
int main() {
Foo<2> okay;
Foo<1> fail; //<- Compile warn/error here! Why?
}
正如您所看到的,我定义了struct Foo
并对其进行了全面的专业化。然后,我定义了内部方法。
当我构建okay
时,它会调用Foo<2>::Foo()
,并采用我给出的定义。但是,当我尝试构建fail
时,它会尝试调用Foo<1>::Foo()
,而这不会工作(打印编译警告,链接失败)。 为什么会这样?
各种编译器的输出,为方便起见:
•GCC 7.2.0:警告:内联功能&#39; Foo&lt; 1&gt; :: Foo()&#39;使用但从未定义
•Clang 5.0.0:警告:内联函数&#39; Foo&lt; 1&gt; :: Foo&#39;未定义[-Wundefined-inline]
•ICC 17 [愉快地工作]
•MSVC 2017 [愉快地工作]
答案 0 :(得分:1)
为什么会这样?
因为你没有定义它。类模板的完全特化基本上产生“常规”类定义。您可以添加,省略或修改类的成员。
它还意味着它没有从主要模板“自动”获得任何东西。您需要明确提供它。因为你没有提供
inline Foo<1>::Foo() {} // Note how we don't need template<> here? Like a regular class
没有这样的人。
至于你发布的“愉快工作”附录,没关系。如果未定义程序使用的实体,则违反了一个定义规则。在形式上,您的程序格式不正确,无需诊断。这意味着行为是未定义的,并且实现可以随意乱用您编译的程序。
要感谢更好的编译器让你知道你搞砸了,而不是滑过这个问题。