【问题标题】:Why is a parameter pack allowed after default arguments?为什么默认参数后允许使用参数包?
【发布时间】:2018-04-30 01:11:12
【问题描述】:

也许我遗漏了一些明显的东西,但以下编译和运行,我不知道为什么。我知道this,但在下面的示例中,参数包的位置和默认参数是相反的。它不违反默认参数必须出现在最后的规则吗?参数包不能有默认值。

#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;
}

这会产生

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

【问题讨论】:

  • 任何参数包的默认值都不为空吗?
  • 是的,默认值为空..

标签: c++ c++11 c++14 default-arguments


【解决方案1】:

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

对于非模板函数,可以在以后添加默认参数 同一范围内的函数声明。中的声明 不同的作用域具有完全不同的默认参数集。 也就是说,内部范围内的声明不获取默认参数 从外部范围的声明,反之亦然。 在给定的函数中 声明,每个参数都在具有默认值的参数之后 参数应具有在此或以前提供的默认参数 声明 or 应该是一个函数参数包。一个默认参数 不应由以后的声明重新定义(甚至不 价值)。 [ 例子:

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

【讨论】:

  • (采摘)这没有回答问题(不是“是它”,而是“为什么允许”)。
  • @KyleStrand 你有,但我没有。相反,我认为最明智的解释是为什么标准允许这样做? 另请注意,该问题未标记为语言律师。一般来说,对于为什么允许这样那样的事情,最明智的答案不是因为法律就是这样。除非,也许你是一名律师。
  • 是的,我接受了这个答案,因为这是法律,但既然你已经提到了......在什么情况下这会有用?我可能应该问一个单独的问题...
  • @cantordust 为了给您省点麻烦:这类“为什么”问题的回答通常是“我们应该怎么知道?您必须询问标准委员会”。成员之间可能有一些讨论记录是否应该允许参数包与可选参数一起使用,但我不会指望它。
  • 但请注意,要求参数包出现在 可选参数之前是没有意义的,因为对于编译器如何区分最后一个参数没有明确的规则pack 参数和可选参数。
【解决方案2】:

作为对 rsp 出色答案的补充,还值得注意的是,这种行为是合乎逻辑的。非默认、非参数包参数不能跟随默认参数而不导致必须指定默认参数的要求——在这种情况下,它不再是默认参数。

例如,如果允许以下情况:

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

非默认的第二个参数意味着对函数的调用需要结构化example(1, 2);,因为第一个参数不能被默认。这不是空参数包的情况。考虑以下函数:

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

在这种情况下,仍然可以通过调用example();来默认x

【讨论】:

  • 此外,void example(int x=0, int y); 有时是允许的:如果先前的声明已经为 y 建立了默认值,则允许。这与您的其余解释相符:这是可以使用 x 的默认值的一种方式。
【解决方案3】:

原因很简单。实际上,参数包总是有一个默认值:参数包可以是空的,这样就不会与缺少默认值必须是最后一个参数的概念相矛盾。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-14
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多