Удобная инициализация структуры C ++ - PullRequest
135 голосов
/ 31 мая 2011

Я пытаюсь найти удобный способ инициализации структур "pod" в C ++.Теперь рассмотрим следующую структуру:

struct FooBar {
  int foo;
  float bar;
};
// just to make all examples work in C and C++:
typedef struct FooBar FooBar;

Если я хочу удобно инициализировать это в C (!), Я мог бы просто написать:

/* A */ FooBar fb = { .foo = 12, .bar = 3.4 }; // illegal C++, legal C

Обратите внимание, что я хочу явно избежатьследующие обозначения, потому что мне кажется, что меня заставляют сломать шею, если я изменю что-нибудь в структуре в будущем:

/* B */ FooBar fb = { 12, 3.4 }; // legal C++, legal C, bad style?

Для достижения того же (или, по крайней мере, аналогичного)) в C ++, как в примере /* A */, мне пришлось бы реализовать идиотский конструктор:

FooBar::FooBar(int foo, float bar) : foo(foo), bar(bar) {}
// ->
/* C */ FooBar fb(12, 3.4);

, который хорош для кипячения воды, но не подходит для ленивых людей (лень - это хорошо, верно?).Кроме того, это в значительной степени так же плохо, как в примере /* B */, поскольку в нем явно не указано, какое значение соответствует какому члену.

Итак, мой вопрос заключается в том, как мне добиться чего-то похожего на /* A */или лучше в C ++?В качестве альтернативы, я мог бы согласиться с объяснением, почему я не должен этого делать (то есть, почему моя умственная парадигма плохая).

РЕДАКТИРОВАТЬ

По удобно , я имею в виду также ремонтопригодно и не резервируется .

Ответы [ 12 ]

0 голосов
/ 19 октября 2018

Для меня самый ленивый способ разрешить встроенную инициализацию - использовать этот макрос.

#define METHOD_MEMBER(TYPE, NAME, CLASS) \
CLASS &set_ ## NAME(const TYPE &_val) { NAME = _val; return *this; } \
TYPE NAME;

struct foo {
    METHOD_MEMBER(string, attr1, foo)
    METHOD_MEMBER(int, attr2, foo)
    METHOD_MEMBER(double, attr3, foo)
};

// inline usage
foo test = foo().set_attr1("hi").set_attr2(22).set_attr3(3.14);

Этот макрос создает атрибут и метод собственной ссылки.

0 голосов
/ 30 ноября 2016

А как насчет этого синтаксиса?

typedef struct
{
    int a;
    short b;
}
ABCD;

ABCD abc = { abc.a = 5, abc.b = 7 };

Только что протестировано на Microsoft Visual C ++ 2015 и на g ++ 6.0.2. Работает нормально.
Вы также можете создать определенный макрос, если хотите избежать дублирования имени переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...