C++ Ожидалось выражение при определении структуры с вложенным объединением

У меня есть структура с вложенным объединением в С++, как показано ниже:

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;
}

Ваш код у меня работает на онлайн ГБД. Какой компилятор вы используете?

Developer Paul 10.04.2019 04:55

Я использую все, что поставляется с Visual Studio 2017 Visual C++ 2015 14.0.24215

David Culbreth 10.04.2019 05:01

C++ не имеет назначенных инициализаторов. Это также не требует typedefs. Все это похоже на C. Вы уверены, что хотите решение на C++? Решение C++ будет использовать конструкторы, а не макросы.

rici 10.04.2019 05:08

Это код, переносимый из решения C в решение C++. Однако у меня сложилось впечатление, что C++ на самом деле является надмножеством C, так что это часть скрытого синтаксиса C. как отметил @DeveloperPaul, это работает в других местах, поэтому должны быть некоторые проблемы с моим компилятором и/или флагами компилятора. Я, вероятно, просто объявлю Value классом, если не найду проблему здесь.

David Culbreth 10.04.2019 05:14

Пусть Value будет структурой и определит разумные конструкторы. В конечном итоге это приведет к тому, что вы после.

aep 10.04.2019 05:17

@aep, если ты напишешь это в ответ с кратким примером, я приму это.

David Culbreth 10.04.2019 05:26

C++ — это нет надмножество C, и у него нет назначенных инициализаторов. GDB не является компилятором, поэтому тот факт, что он поддерживает синтаксис C и C++, не имеет значения. И нет никакой разницы между struct и class в C++, кроме видимости nember по умолчанию (public для struct и private для class).

rici 10.04.2019 05:40

C++ является надмножеством подмножества C (кстати, это верно для любых двух множеств).

n. 1.8e9-where's-my-share m. 10.04.2019 05:48

С++ 20 будет иметь назначенные инициализаторы; некоторые компиляторы уже поддерживают его

M.M 10.04.2019 06:02
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
9
409
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Живой код.

В C++ объединения могут иметь конструкторы. В вашем struct вы можете определить перегрузки конструктора для инициализации члена союза вместе с тегом союза, то есть type.

Другие вопросы по теме

Похожие вопросы

Пароль с использованием c-массива
Как предотвратить многократный выбор одной и той же опции/значения в операторе switch
При использовании std::vector::push_back для вставки неизвестного количества элементов следует ли проверять std::vector::max_size при каждом нажатии?
Преобразование статического массива constexpr в параметр шаблона в С++ 11
Очень странная ошибка при попытке напечатать шестнадцатеричный хеш Blake2 файла
Как проверить дескриптор USB HID как недействительный из-за повторного подключения устройства
Перемещение функции из консольного приложения в проект общей библиотеки, похоже, приводит к несвязанной ошибке компиляции
Символ 'T' не разрешается в строке после ключевого слова шаблона
Как использовать массивы сложных переменных в C++?
Как записать данные в стандартный ввод для использования отдельным потоком, ожидающим ввода из стандартного ввода?