考虑以下最小示例:
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 [工作愉快]
最佳答案
Why does this happen?
因为你没有定义它。类模板的完全特化本质上产生了一个“常规”类定义。您可以添加、省略或修改类的成员。
这也意味着它不会“自动”从主模板中获取任何内容。您需要明确提供它。而且因为你没有提供
inline Foo<1>::Foo() {} // Note how we don't need template<> here? Like a regular class
没有这样的c'tor。
至于你发的“工作愉快”的补遗,无所谓。如果您未定义程序使用的实体,则违反了单一定义规则。形式上,您的程序格式错误,无需诊断。这意味着该行为是未定义的,并且实现可以随意扰乱您认为合适的已编译程序。
感谢更好的编译器让你知道你搞砸了,而不是滑过这个问题。
关于c++ - 定义的 `inline` 找不到用于特化的模板方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46824445/