考虑以下类模板:
template <typename>
struct S
{
template <typename T>
void f(T) { /* ... */ }
};
可以提供显式实例化定义(或通过extern template
的
声明)
S
本身和S::f
:
template struct S<int>;
template void S<int>::f<int>(int);
但是,如果我们使用构造函数模板而不是常规成员函数模板,情况会怎样?
template <typename>
struct S
{
template <typename T>
S(T) { /* ... */ }
};
根据 Clang 的说法,仍然可以为 S
本身提供一个
显式实例化定义,但不能为构造函数提供:
template struct S<int>; // OK
template S<int>::S<int>(int); // ERROR (!)
error: out-of-line constructor for 'S' cannot have template arguments template S<int>::S<int>(int); ^~~~~~
另一方面,GCC 似乎接受这两种定义。请参阅 godbolt.org 上的this live example.
像
template S<int>::S<int>(int)
这样的定义是合法的,还是Clang拒绝它是正确的?