【问题标题】:Initialize parameter into constructor, other than the first one将参数初始化为构造函数,而不是第一个
【发布时间】:2019-06-23 22:48:14
【问题描述】:

我想在以下场景中显式更改结构的构造函数中的第二个参数。有没有可能,如果有,怎么做?

struct foo{
    int x;
    int y;
    foo(int a=4, int b=6){
        x=a;
        y=b;
    }
};

int main(){
    foo *f = new foo();
    cout<<f->x<<" "<<f->y<<endl;
   //4 6 
    foo *g = new foo(3,4);
    cout<<g->x<<" "<<g->y<<endl;
    //3 4
    foo *h = new foo(3);
    cout<<h->x<<" "<<h->y<<endl;
   //3 6
   //Can something like this be 
   //done in C++, if I want
   //to change the value of the 
   //second variable only
    foo *k = new foo(b = 13);

return 0;

}

【问题讨论】:

标签: c++ constructor


【解决方案1】:

有可能吗,如果可以,怎么做?

构造函数是不可能的。一般来说,c++ 不支持函数的命名关键字参数,如果你想在它后面传递一个非默认值,即使它们有默认值也不能跳过。

如果你使用默认的成员初始化器,那么从 C++20 开始使用指定初始化器,使用列表初始化语法的构造函数是可能的:

struct foo{
    int x = 4;
    int y = 6;
};

int main(){
    foo f {.y = 4};
}

您可以通过标签调度实现类似的效果;不需要未来的标准:

struct foo{
    int x = 4;
    int y = 6;

    enum Xtag { Xinit };
    enum Ytag { Yinit };

    foo(int a, int b) : x(a), y(b) {}
    foo(Xtag, int a)  : x(a) {}
    foo(Ytag, int b)  : y(b) {}
};

int main(){
    foo f(foo::Yinit, 4);
}

一种使用 lambda 的解决方案,无需修改现有类即可使用。以下适用于您对foo 的定义:

auto make_foo_x4 = [](int b) {
    return foo(4, b);
};
foo f = make_foo_y(4);

缺点是我们必须显式重复默认值x,因此如果在类定义中更改默认值,这可能会破坏假设。

【讨论】:

  • std::bind 在技术上也适用于此吗?我对它还不够熟悉,无法确定。
  • @Chipster 如果您首先编写一个调用构造函数的函数,则可以,但使用 lambda 会更简单。甚至 lambda 都比 tag dispatch 复杂,但是如果你想扩展一个不可修改的第三方类,那么 lambda 肯定是一个选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-06
  • 1970-01-01
  • 1970-01-01
  • 2018-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多