找不到用于专用化的定义的"内联"模板方法

Defined `inline` Template Method Isn't Found for Specialization

本文关键字:内联 模板方法 用于 定义 找不到 专用      更新时间:2023-10-16

请考虑以下最小示例:

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:警告:使用内联函数"Foo<1>::Foo()",但从未定义
• Clang 5.0.0:警告:内联函数"Foo<1>::Foo"未定义 [-Wundefined-inline]
• ICC 17 [愉快地工作]
• MSVC 2017 [快乐工作]

为什么会这样?

因为你没有定义它。类模板的完全专用化本质上会产生"常规"类定义。您可以添加、省略或修改类的成员。

这也意味着它不会"自动"从主模板中获取任何内容。您需要明确提供它。既然你没有提供

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

没有这样的c'tor。

至于你发布的"快乐工作"附录,没关系。如果未定义程序使用的实体,则会违反一个定义规则。从形式上讲,您的程序格式不正确,无需诊断。这意味着行为是未定义的,并且实现可以自由地弄乱您编译的程序,因为它们认为合适。

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