找不到用于专业化的定义的“内联”模板方法
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"补遗,无所谓。如果您未定义程序使用的实体,则违反了单一定义规则。形式上,您的程序格式错误,无需诊断。这意味着该行为是未定义的,并且实现可以随意扰乱您认为合适的已编译程序。
感谢更好的编译器让你知道你搞砸了,而不是滑过这个问题。
考虑以下最小示例:
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"补遗,无所谓。如果您未定义程序使用的实体,则违反了单一定义规则。形式上,您的程序格式错误,无需诊断。这意味着该行为是未定义的,并且实现可以随意扰乱您认为合适的已编译程序。
感谢更好的编译器让你知道你搞砸了,而不是滑过这个问题。