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

Defined `inline` Template Method Isn't Found for 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(),而 这不起作用 (打印编译警告,link 失败). 为什么会这样?


各种编译器的输出,为了您的方便:
• GCC 7.2.0:警告:内联函数'Foo<1>::Foo()'已使用但从未定义
• Clang 5.0.0:警告:内联函数 'Foo<1>::Foo' 未定义 [-Wundefined-inline]
• ICC 17 [工作愉快]
• MSVC 2017 [工作愉快]

Why does this happen?

因为你没有定义它。 class 模板的完全特化本质上产生了 "regular" class 定义。您可以添加、省略或修改 class 的成员。

这也意味着它不会从主模板中获取任何东西 "automagically"。您需要明确提供它。而且因为你没有提供

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

没有这样的c'tor。

至于你发的"works happily"补遗,无所谓。如果您未定义程序使用的实体,则违反了单一定义规则。形式上,您的程序格式错误,无需诊断。这意味着该行为是未定义的,并且实现可以随意扰乱您认为合适的已编译程序。

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