У меня есть структура с вложенным объединением в С++, как показано ниже:
typedef enum {
VAL_BOOL,
VAL_NIL,
VAL_NUMBER,
} ValueType;
typedef struct {
ValueType type;
union {
bool boolean;
double number;
} as;
} Value;
Я пытаюсь создать функцию #define
, чтобы сделать инициализацию этих значений более читаемой, и это то, что у меня есть до сих пор, но она не компилируется:
#define NUMBER_VAL(value) ((Value){ VAL_NUMBER, { .number = value } })
Приведенная выше реализация генерирует следующую ошибку во время компиляции, когда используется NUMBER_VAL(val)
: expected an expression
Цель здесь состоит в том, чтобы иметь возможность определить Value
, написав что-то вроде следующего:
double dub = 1.23;
Value val = NUMBER_VAL(dub);
или передать его функции, например:
void process_value(Value value);
...
double dub = 45.6;
process_value(NUMBER_VAL(dub));
Есть ли способ преобразовать это #define
-ция в выражение, которое позволило бы мне использовать его таким образом? Или мой единственный вариант здесь написать правильную функцию для создания этих структур для меня?
Для справки, я знаю, что следующее сработает, но я надеялся на что-то более лаконичное.
Value NUMBER_VAL(double value) {
Value val;
val.type = VAL_NUMBER;
val.as.number = value;
return val;
}
Я использую все, что поставляется с Visual Studio 2017 Visual C++ 2015 14.0.24215
C++ не имеет назначенных инициализаторов. Это также не требует typedefs. Все это похоже на C. Вы уверены, что хотите решение на C++? Решение C++ будет использовать конструкторы, а не макросы.
Это код, переносимый из решения C в решение C++. Однако у меня сложилось впечатление, что C++ на самом деле является надмножеством C, так что это часть скрытого синтаксиса C. как отметил @DeveloperPaul, это работает в других местах, поэтому должны быть некоторые проблемы с моим компилятором и/или флагами компилятора. Я, вероятно, просто объявлю Value
классом, если не найду проблему здесь.
Пусть Value
будет структурой и определит разумные конструкторы. В конечном итоге это приведет к тому, что вы после.
@aep, если ты напишешь это в ответ с кратким примером, я приму это.
C++ — это нет надмножество C, и у него нет назначенных инициализаторов. GDB не является компилятором, поэтому тот факт, что он поддерживает синтаксис C и C++, не имеет значения. И нет никакой разницы между struct
и class
в C++, кроме видимости nember по умолчанию (public
для struct
и private
для class
).
C++ является надмножеством подмножества C (кстати, это верно для любых двух множеств).
С++ 20 будет иметь назначенные инициализаторы; некоторые компиляторы уже поддерживают его
В C++ объединения могут иметь конструкторы. В вашем struct
вы можете определить перегрузки конструктора для инициализации члена союза вместе с тегом союза, то есть type
.
Ваш код у меня работает на онлайн ГБД. Какой компилятор вы используете?