Arm*_*yan 28 c++ member-functions default-value
struct X
{
X():mem(42){}
void f(int param = mem) //ERROR
{
//do something
}
private:
int mem;
};
Run Code Online (Sandbox Code Playgroud)
任何人都可以给我一个原因,为什么这在C++中是非法的?!也就是说,我知道这是一个错误,我知道错误意味着什么,我只是无法理解为什么这是非法的!
Naw*_*waz 41
你的代码(简化):
struct X
{
int mem;
void f(int param = mem); //ERROR
};
Run Code Online (Sandbox Code Playgroud)
您希望将非静态成员数据用作成员函数的参数的默认值.想到的第一个问题是:默认值属于哪个类的特定实例mem?
X x1 = {100}; //mem = 100
X x2 = {200}; //mem = 200
x1.f(); //param is 100 or 200? or something else?
Run Code Online (Sandbox Code Playgroud)
你的答案可能是100因为f()在对象上调用x1 它有mem = 100.如果是这样,那么它需要实现f()如下:
void f(X* this, int param = this->mem);
Run Code Online (Sandbox Code Playgroud)
这反过来要求在初始化其他参数之前首先初始化第一个参数.但是C++标准没有指定函数参数的任何初始化顺序.因此,这是不允许的.其原因与C++标准不允许这样的原因相同:
int f(int a, int b = a); //§8.3.6/9
Run Code Online (Sandbox Code Playgroud)
事实上,§8.3.6/ 9明确地说,
每次调用函数时都会计算默认参数.函数参数的评估顺序未指定.因此,函数的参数不应在默认参数表达式中使用,即使它们未被计算.
本节的其余部分是一个有趣的阅读.
一个与"默认"参数相关的有趣主题(尽管与此主题无关):
必须在编译时知道默认参数.当你谈到像函数调用这样的东西时,那么函数在编译时是已知的,即使返回值不是,所以编译器可以生成该代码,但是当你默认为成员变量时,编译器不会知道在编译时在哪里找到该实例,这意味着它实际上必须通过参数(this)来查找mem.请注意,你不能做类似的事情void func(int i, int f = g(i));,两者实际上是相同的限制.
我也认为这种限制很愚蠢.但是,C++充满了愚蠢的限制.
正如DeadMG上面提到的,有点像
void func(int i, int f = g(i))
出于同样的原因是非法的.但是,我认为这不仅仅是一个愚蠢的限制.为了允许这样的构造,我们需要限制函数参数的评估顺序(因为我们需要在this-> mem之前计算它),但是c ++标准明确地拒绝了对评估顺序的任何假设.
| 归档时间: |
|
| 查看次数: |
4948 次 |
| 最近记录: |