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

时间:2019-06-18 13:53:52

标签: 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;
}

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在这个问题上非常清楚:定义和所有声明上的默认模板参数应合并。 后面的声明没有特殊的例外,对吗?

1 个答案:

答案 0 :(得分:8)

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

  

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

t之后

// Mind the default template argument
template <typename T = int>
struct Test;

应考虑并使用int默认参数,因为未指定任何参数。