参数包函数参数可以默认吗?
Can parameter pack function arguments be defaulted?
这是 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
)。铿锵声说:
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
哪个编译器是正确的?
从 8.3.6 ([dcl.fct.default])/3:
A default argument shall not be specified for a parameter pack.
从 8.3.6 ([dcl.fct.default])/4:
In a given function declaration, each parameter subsequent to a parameter with a default argument shall have a default argument supplied in this or a previous declaration or shall be a function parameter pack.
所以这允许像 void f(int a = 10, Args ... args)
这样的代码,或者确实像你的第一个片段。 (感谢@T.C.找第二句!)
A Kerrek SB 说,这是不可能的。相反,您可以使用 std::tuple
template <class ... Args>
void foo( std::tuple<Args...> t = std::tuple<int>(0) )
{}
这是 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
)。铿锵声说:
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
哪个编译器是正确的?
从 8.3.6 ([dcl.fct.default])/3:
A default argument shall not be specified for a parameter pack.
从 8.3.6 ([dcl.fct.default])/4:
In a given function declaration, each parameter subsequent to a parameter with a default argument shall have a default argument supplied in this or a previous declaration or shall be a function parameter pack.
所以这允许像 void f(int a = 10, Args ... args)
这样的代码,或者确实像你的第一个片段。 (感谢@T.C.找第二句!)
A Kerrek SB 说,这是不可能的。相反,您可以使用 std::tuple
template <class ... Args>
void foo( std::tuple<Args...> t = std::tuple<int>(0) )
{}