为什么默认参数不能依赖于非默认参数?

why can't default argument depend on non-default argument?

本文关键字:参数 默认 不能 为什么 依赖于      更新时间:2023-10-16

考虑以下构造函数:

class MyClass {
    MyClass(unsigned int dimension, std::vector vector=unitaryVector(dimension));
};

其中 unitaryVector(d)是返回d dimensions中随机std::vector的函数。

这给出以下编译器错误:

error: default argument references parameter 'dimension'
    MyClass(unsigned int dimension, std::vector vector=unitaryVector(dimension));

为什么这个成语在C 11中不有效?这似乎很明显:如果提供了vector参数,则INIT vector作为参数的副本,否则,将函数调用并作为返回值的副本调用函数。编译器为什么不能理解这一点?

c 标准禁止它。

dcl.fct.default

9 每次调用函数时都会评估默认参数 没有关于相应参数的参数。参数不得 在默认参数中显示为潜在评估的表达。 在默认参数中声明的函数的参数在 范围并可以隐藏名称空间和类成员名称。

[示例:

int a;
int f(int a, int b = a);            // error: parameter a
                                    // used as default argument
typedef int I;
int g(float I, int b = I(2));       // error: parameter I found
int h(int a, int b = sizeof(a));    // OK, unevaluated operand

- 结束示例]

请注意,如果未提供默认参数在呼叫站点上

Intro.ectution (强调我的)

11: [注意:评估A full-Expression 可以包括对亚表达的评估是不是词汇的一部分 全表达。例如,涉及评估的子表达 默认参数([[dcl.fct.default])被认为是 在调用函数的表达式中,不是表达式 定义默认参数。 - 终止注]


您可以简单地超载构造函数并委派它:

class MyClass {
    explicit MyClass(unsigned int dimension) 
        : MyClass(dimension, unitaryVector(dimension))  //delegation
    {  }
    MyClass(unsigned int dimension, std::vector vector);
};

脚注:制作单个参数构造函数explicit

是一件好事

一种选择是使用

class MyClass {
    MyClass(unsigned int dimension, std::vector const& vector) :
            dimension(dimension), vector(vector) {}
    MyClass(unsigned int dimension) :
            MyClass(dimension, unitaryVector(dimension)) {}
};

(当然,当您想在课堂中存储dimensionvector时)。

,因为默认参数本身必须完整,以便编译器可以简单地替换呼叫。(本地)变量dimension尚未创建,您正在尝试使用它,因此错误。但是,这将有效:

int _def_dim=10;
class MyClass {
    MyClass(unsigned int dimension, std::vector vector=unitaryVector(_def_dim));
};

我不确定标准是什么,但是对于编译器而言,处理此类角案很难。

编辑(有关完整),从此答案中获取:

每次调用函数时,都会评估默认参数。这 函数参数的评估顺序未指定。 因此,默认值不得使用函数的参数 即使没有评估论证表达式。