如果放置在该类模板的定义之后,则该类模板的默认模板参数无效。

Igo*_*r G 7 c++ language-lawyer

请考虑以下示例:

// 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;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码可以通过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;
}
Run Code Online (Sandbox Code Playgroud)

这也适用于所有三个编译器。

但是,如果我将默认参数放在类模板的定义之后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;
}
Run Code Online (Sandbox Code Playgroud)

是MSVC错误吗?
我认为cppreference在这个问题上很清楚:定义和所有声明上的默认模板参数应合并。无特殊异常的声明做出如下定义,对不对?

Nat*_*ica 8

这是一个错误。每[temp.param] / 12

可以使用的默认模板参数集是通过以默认函数参数([dcl.fct.default])相同的方式合并模板的所有先前声明中的默认参数而获得的。

自从t之后

// Mind the default template argument
template <typename T = int>
struct Test;
Run Code Online (Sandbox Code Playgroud)

int默认参数应考虑和因为没有指定参数使用。