是否可以在c++中初始化结构,如下所示:

struct address {
    int street_no;
    char *street_name;
    char *city;
    char *prov;
    char *postal_code;
};

address temp_address = { .city = "Hamilton", .prov = "Ontario" };

这里和这里的链接提到,这种样式只能在C中使用。如果是这样,为什么在c++中不能使用呢?是否有任何潜在的技术原因,为什么它不是在c++中实现的,或者使用这种风格是不好的做法。我喜欢使用这种初始化方式,因为我的结构体很大,而且这种样式可以让我清楚地了解分配给哪个成员的值。

请与我分享是否有其他方法可以达到同样的可读性。

在提出这个问题之前,我已参考以下连结:

C/ c++ for AIX C结构初始化变量 c++中使用标记的静态结构初始化 c++ 11正确的结构初始化


当前回答

受到这个非常简洁的答案的启发:(https://stackoverflow.com/a/49572324/4808079)

你可以使用lamba闭包:

// Nobody wants to remember the order of these things
struct SomeBigStruct {
  int min = 1;
  int mean = 3 ;
  int mode = 5;
  int max = 10;
  string name;
  string nickname;
  ... // the list goes on
}

.

class SomeClass {
  static const inline SomeBigStruct voiceAmps = []{
    ModulationTarget $ {};
    $.min = 0;  
    $.nickname = "Bobby";
    $.bloodtype = "O-";
    return $;
  }();
}

或者,如果你想要非常花哨的话

#define DesignatedInit(T, ...)\
  []{ T ${}; __VA_ARGS__; return $; }()

class SomeClass {
  static const inline SomeBigStruct voiceAmps = DesignatedInit(
    ModulationTarget,
    $.min = 0,
    $.nickname = "Bobby",
    $.bloodtype = "O-",
  );
}

这样做有一些缺点,主要与未初始化的成员有关。从链接的答案评论说,它编译有效,虽然我没有测试它。

总的来说,我认为这是一个很好的方法。

其他回答

受到这个非常简洁的答案的启发:(https://stackoverflow.com/a/49572324/4808079)

你可以使用lamba闭包:

// Nobody wants to remember the order of these things
struct SomeBigStruct {
  int min = 1;
  int mean = 3 ;
  int mode = 5;
  int max = 10;
  string name;
  string nickname;
  ... // the list goes on
}

.

class SomeClass {
  static const inline SomeBigStruct voiceAmps = []{
    ModulationTarget $ {};
    $.min = 0;  
    $.nickname = "Bobby";
    $.bloodtype = "O-";
    return $;
  }();
}

或者,如果你想要非常花哨的话

#define DesignatedInit(T, ...)\
  []{ T ${}; __VA_ARGS__; return $; }()

class SomeClass {
  static const inline SomeBigStruct voiceAmps = DesignatedInit(
    ModulationTarget,
    $.min = 0,
    $.nickname = "Bobby",
    $.bloodtype = "O-",
  );
}

这样做有一些缺点,主要与未初始化的成员有关。从链接的答案评论说,它编译有效,虽然我没有测试它。

总的来说,我认为这是一个很好的方法。

在gnuc++中(似乎从2.5开始就过时了,很久以前了:)看到答案在这里:使用标签初始化C结构。它可以工作,但如何?),可以像这样初始化一个结构体:

struct inventory_item {
    int bananas;
    int apples;
    int pineapples;
};

inventory_item first_item = {
    bananas: 2,
    apples: 49,
    pineapples: 4
};

我可能在这里遗漏了一些东西,为什么不呢:

#include <cstdio>    
struct Group {
    int x;
    int y;
    const char* s;
};

int main() 
{  
  Group group {
    .x = 1, 
    .y = 2, 
    .s = "Hello it works"
  };
  printf("%d, %d, %s", group.x, group.y, group.s);
}

在我的问题没有得到令人满意的结果之后(因为c++没有为结构实现基于标记的init),我使用了我在这里找到的技巧:c++结构体的成员默认初始化为0吗?

对你来说,它相当于这样做:

address temp_address = {}; // will zero all fields in C++
temp_address.city = "Hamilton";
temp_address.prov = "Ontario";

这当然是最接近您最初想要的(除那些您想初始化的字段外,所有字段都为零)。

如果你想清楚每个初始化值是什么,只需要把它分成多行,并在每一行上加一个注释:

address temp_addres = {
  0,  // street_no
  nullptr,  // street_name
  "Hamilton",  // city
  "Ontario",  // prov
  nullptr,  // postal_code
};