请考虑以下示例:
// Mind the default template argument
template <typename T = int>
struct Test;
template <typename T>
struct Test
{
};
template <typename T>
struct Test;
int main()
{
Test<> t;
return 0;
}
MSVC 19,gcc 8和clang 8可以成功地编译上面的代码。
现在,让我们将默认模板参数移到类模板的定义上:
template <typename T>
struct Test;
// Mind the default template argument
template <typename T = int>
struct Test
{
};
template <typename T>
struct Test;
int main()
{
Test<> t;
return 0;
}
这同样适用于所有三个编译器。
但是,如果我将默认参数放置在Test
类模板的定义之后,则Visual Studio将拒绝编译源代码并抱怨
标有(!)的行:模板参数太少
template <typename T>
struct Test;
template <typename T>
struct Test
{
};
// Mind the default template argument
template <typename T = int>
struct Test;
int main()
{
Test<> t; // (!)
return 0;
}
这是MSVC错误吗?
我认为cppreference在这个问题上非常清楚:定义和所有声明上的默认模板参数应合并。 后面的声明没有特殊的例外,对吗?
答案 0 :(得分:8)
这是一个错误。每个[temp.param]/12
可使用的默认 template-arguments 集合是通过合并模板的所有先前声明中的默认参数而获得的,其方式与默认函数参数([dcl.fct.default] )。
自t
之后
// Mind the default template argument
template <typename T = int>
struct Test;
应考虑并使用int
默认参数,因为未指定任何参数。