简体   繁体   English

为什么默认参数后允许参数包?

[英]Why is a parameter pack allowed after default arguments?

Maybe I'm missing something obvious, but the following compiles and runs, and I'm not sure why. 也许我错过了一些明显的东西,但是下面的编译和运行,我不知道为什么。 I am aware of this , but in the example below the position of the parameter pack and the default argument are reversed. 我知道这一点 ,但在下面的示例中,参数包的位置和默认参数是相反的。 Doesn't it violate the rule that default arguments have to appear last? 它是否违反了默认参数必须最后出现的规则? The parameter pack cannot have a default value. 参数包不能具有默认值。

#include <iostream>
#include <string>
#include <tuple>

template<typename ... Ts>
struct Test
{
    int i;
    std::string str;

    Test(int _i = 0, Ts&& ... _ts)
        :
          i(_i),
          str(std::get<0>(std::forward_as_tuple(std::forward<Ts>(_ts)...)))
    {}
};

int main()
{
    Test<std::string> t(1, "huh??");
    std::cout << "t.i = " << t.i << ", t.str = " << t.str << "\n";

    return 0;
}

This produces 这产生了

t.i = 1, t.str = huh??

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

For non-template functions, default arguments can be added in later declarations of a function in the same scope. 对于非模板函数,可以在稍后的同一范围内的函数声明中添加默认参数。 Declarations in different scopes have completely distinct sets of default arguments. 不同范围内的声明具有完全不同的默认参数集。 That is, declarations in inner scopes do not acquire default arguments from declarations in outer scopes, and vice versa. 也就是说,内部作用域中的声明不从外部作用域中的声明中获取默认参数,反之亦然。 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. 在给定的函数声明中,具有默认参数的参数之后的每个参数都应具有在此声明或先前声明中提供的默认参数,或者应为函数参数包。 A default argument shall not be redefined by a later declaration (not even to the same value). 默认参数不应由后来的声明(甚至不是相同的值)重新定义。 [ Example: [例如:

 void g(int = 0, ...); // OK, ellipsis is not a parameter. So it can follow a parameter with a default argument 

As an addition to the great answer by rsp, it's also worth noting that this behavior makes logical sense. 作为rsp的优秀答案的补充,值得注意的是,这种行为具有逻辑意义。 Non-default, non-parameter-pack arguments cannot follow a default argument without resulting the in the requirement that the default argument has to be specified--in which case it is no longer a default argument. 非默认的非参数包参数不能遵循默认参数,而不会导致必须指定默认参数 - 在这种情况下它不再是默认参数。

For example, if the following were allowed: 例如,如果允许以下内容:

void example(int x=0, int y);

The non-default second argument would mean a call to function would need to be structured example(1, 2); 非默认的第二个参数意味着对函数的调用需要结构化example(1, 2); as the first parameter cannot be defaulted. 因为第一个参数不能默认。 This is not the case for an empty parameter pack. 空参数包不是这种情况。 Consider the following function: 考虑以下功能:

template <typename... T> void example(int x = 0, T&&... t);

In this case it is still possible to default x by calling example(); 在这种情况下,仍然可以通过调用example();来默认x example();

The why of it is simple. 它的原因很简单。 Effectively parameter packs always have a default: Parameter packs can be empty, so that won't contradict the concept that missing defaults must be the last arguments. 有效的参数包总是有一个默认值:参数包可以是空的,这样就不会与缺少默认值必须是最后一个参数的概念相矛盾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM