定义的“内联”模板方法没有找到专业化

时间:2017-10-19 07:12:48

标签: c++ templates methods template-specialization

考虑以下最小例子:

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 [愉快地工作]

1 个答案:

答案 0 :(得分:1)

  

为什么会这样?

因为你没有定义它。类模板的完全特化基本上产生“常规”类定义。您可以添加,省略或修改类的成员。

它还意味着它没有从主要模板“自动”获得任何东西。您需要明确提供它。因为你没有提供

inline Foo<1>::Foo() {} // Note how we don't need template<> here? Like a regular class

没有这样的人。

至于你发布的“愉快工作”附录,没关系。如果未定义程序使用的实体,则违反了一个定义规则。在形式上,您的程序格式不正确,无需诊断。这意味着行为是未定义的,并且实现可以随意乱用您编译的程序。

要感谢更好的编译器让你知道你搞砸了,而不是滑过这个问题。