【问题标题】:Can parameter pack function arguments be defaulted?参数包函数参数可以默认吗?
【发布时间】:2015-05-19 20:47:46
【问题描述】:

这是 gcc 4.9.2 和 clang 3.5.2 的重点 分歧。程序:

template<typename ...Ts>
int foo(int i = 0, Ts &&... args)
{
    return i + sizeof...(Ts);
}

int main()
{
    return foo();
}

编译时没有来自 gcc (-std=c++11 -Wall -pedantic) 的注释。 Clang 说:

error: missing default argument on parameter 'args'

foo 修改为:

template<typename ...Ts>
int foo(int i = 0, Ts &&... args = 0)
{
    return i + sizeof...(Ts);
}

clang 没有抱怨,但 gcc 说:

error: parameter pack ‘args’ cannot have a default argument

哪个编译器是正确的?

【问题讨论】:

  • 你可以通过重载来解决它:template &lt;typename... Ts&gt; int foo(int i, Ts&amp;&amp;...) { return i + sizeof...(Ts); } inline int foo() { return foo(0); }

标签: c++ c++11 gcc clang variadic-templates


【解决方案1】:

从 8.3.6 ([dcl.fct.default])/3:

不应为参数包指定默认参数。

从 8.3.6 ([dcl.fct.default])/4:

在给定的函数声明中,带有默认实参的形参后面的每个形参都应在此声明或先前声明中提供默认实参,或者应为函数形参包。

所以这允许像void f(int a = 10, Args ... args) 这样的代码,或者确实像你的第一个sn-p。 (感谢@T.C. 查找第二句话!)

【讨论】:

  • [dcl.fct.default]/4 ("在给定的函数声明中,带有默认参数的参数后面的每个参数都应在此声明或先前声明中提供默认参数,或者应为一个函数参数包。”)似乎允许第一个版本。
  • @KerrekSB 是的,所以它允许 GCC 接受的版本。
  • @T.C.:是的,谢谢,如果您不介意的话,我已将其吸收到帖子中 :-)
  • clang 错误提交:2302823029
  • 已在主干中修复,因此将在下一版本的 clang 中修复。真快!
【解决方案2】:

Kerrek SB 说,这是不可能的。相反,您可以做的是使用std::tuple

template <class ... Args>
void foo( std::tuple<Args...> t = std::tuple<int>(0) )
{}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-01
    • 2012-07-25
    • 2011-04-18
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    相关资源
    最近更新 更多