Есть такая декларация:
struct func {
const char * name;
int argc;
union {
int (*f0)(void *);
int (*f1)(void *, int );
} f;
};
Есть такая функция
int foo(void * p, int v) { return 42; };
Нужно написать инициализатор типа этого:
func fdef = { "meth1" , 1, {.f1 = foo} };
Но чего-то не выходит каменный цветок, во всяком случае в VS2017
Ругается на '.' тут:
func fdef = { "meth1" , 1, {.f1 = foo} };
---------------------------^
Можно как-то победить это безобразие?
Re: С++ union initialization
Здравствуйте, c-smile, Вы писали:
CS>Ругается на '.' тут:
CS>CS>func fdef = { "meth1" , 1, {.f1 = foo} };
CS>---------------------------^
CS>
CS>Можно как-то победить это безобразие?
В C++ designated initializers вошли с C++20.
Как расширение в MSVC их не было тоже.
Русский военный корабль идёт ко дну!
Re: С++ union initialization
От:
Reset
Дата: 21.03.20 05:28
Оценка:
Во-первых, открой для себя
божественный болт . Там правда нет 2017, зато он позволяет переключаться между компиляторами и ты сможешь открыть для себя, во-вторых, /std:c++latest (в сообщении об ошибке компиляции при выборе последнего MSVC). Ну и, в-третьих, он позволяет шарить код, давая
ссылку на него.
Re: С++ union initialization
Здравствуйте, c-smile, Вы писали:
CS>Но чего-то не выходит каменный цветок, во всяком случае в VS2017
CS>Можно как-то победить это безобразие?
Накидай constexpr конструкторов, будет такая же статическая инициализация.
Если перергузки конструктора по типу активного мембера выглядят ненадёжными или непонятными, добавить тип-тег
Примерно так
struct func {
const char * name;
int argc;
static struct tag_f0_t {} tag_f0;
static struct tag_f1_t {} tag_f1;
union U {
int (*f0)(void *);
int (*f1)(void *, int );
constexpr U(decltype(f0) f0, tag_f0) : f0(f0) {}
constexpr U(decltype(f1) f1, tag_f1) : f1(f1) {}
} f;
};
func fdef = { "meth1" , 1, { foo, tag_f0 } };
Русский военный корабль идёт ко дну!
Re: С++ union initialization
Здравствуйте, c-smile, Вы писали:
CS>Но чего-то не выходит каменный цветок, во всяком случае в VS2017
CS>Ругается на '.' тут:
CS>Можно как-то победить это безобразие?
Ну, ругается потому, что
Designated initializers появляются только с C++20.
Чтобы победить, я бы сделал вложенный union полностю анонимным (убрал бы имя члена f) и снабдил бы класс func набором необходимых конструкторов:
http://coliru.stacked-crooked.com/a/76e0848b39685871
struct func {
using F0 = int (void *);
using F1 = int (void *, int );
const char * name {};
int argc {};
union {
F0* f0 {};
F1* f1;
};
func() = default ;
func(const char * name, F0* f0) : name(name), argc(0), f0(f0) { }
func(const char * name, F1* f1) : name(name), argc(1), f1(f1) { }
};
int foo(void * p, int v) { return 42; }
int main() {
func fdef = { "meth1" , foo };
}
И про
default member initializers не забываем — C++ же, все-таки
--
Не можешь достичь желаемого — пожелай достигнутого.
Re: С++ union initialization
Здравствуйте, c-smile, Вы писали:
CS>CS>func fdef = { "meth1" , 1, {.f1 = foo} };
CS>
CS>Но чего-то не выходит каменный цветок, во всяком случае в VS2017
CS>Можно как-то победить это безобразие?
Это компилируется, если тип файла .c.
With best regards
Pavel Dvorkin
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить