Инициализация статической структуры без назначенных инициализаторов?

Следующий пример назначенного инициализатора действителен в Visual Studio 2019 с /std:c++latest, но мне интересно, как выполнить то же самое без назначенных инициализаторов в Visual Studio 2017.

Я использую C++ и понимаю, что есть объектно-ориентированный способ сделать это, но я НЕ спрашиваю, как воссоздать это на C++ с помощью конструкторов. Это делает пометку для этого вопроса немного запутанной, извините за путаницу.

Я также борюсь с терминологией здесь. Просто чтобы подтвердить, является ли &(struct Foo) составным литералом? И это достижение статической инициализации времени компиляции? Можно ли здесь как-то использовать constexpr?

// Header
struct Foo
{
    void (*Bar)();
};

extern struct Foo *FooAPI;

// Source
static void Bar()
{

}

static struct Foo *FooAPI = &(struct Foo) { // Error: Expecting an expression
    .Bar = Bar
};

person Stradigos    schedule 07.01.2021    source источник
comment
Ваш вопрос имеет какое-либо отношение к C? Если нет, пожалуйста, удалите тег.   -  person Eugene Sh.    schedule 08.01.2021
comment
В каком-то смысле да.   -  person Stradigos    schedule 08.01.2021
comment
.Bar = Bar; --› .Bar = Bar. Также: void *(Bar)(); --› void (*Bar)();   -  person dbush    schedule 08.01.2021
comment
C и C++ — это два очень разных языка, поэтому, пожалуйста, не отмечайте оба языка. Код, который вы показываете, не является допустимым кодом C++, потому что да, он действительно использует составные литералы.   -  person Some programmer dude    schedule 08.01.2021


Ответы (1)


struct Foo
{
    void *(Bar)();
};

Foo::Bar — это функция-член, которая возвращает void*. C не имеет функций-членов, поэтому в C это было бы неправильно.

{
    .Bar = Bar;
}

Это неправильно в обоих языках. Здесь нельзя ставить точку с запятой. Решение: Уберите точку с запятой. По желанию заменить запятой.

Кроме того, Foo::Bar является функцией-членом, поэтому вы не можете предоставить для нее инициализатор. Возможно, вы предполагали, что Foo::Bar будет указателем на функцию, которая возвращает void. Синтаксис для этого будет следующим:

struct Foo
{
    void (*Bar)();
};
// or nicer way:
struct Foo
{
    using Fun = void();
    Fun* Bar;
};
extern struct Foo *FooAPI;
static struct Foo *FooAPI =

Переменная, которая была объявлена ​​extern, не может быть повторно объявлена ​​static. Решение: удалите static.

Просто чтобы подтвердить, является ли &(struct Foo) составным литералом?

(struct Foo) { ... } — составной литерал. Унарный & является адресом оператора, а составной литерал является операндом в этом случае.

Инициализация статической структуры без назначенных инициализаторов?

Просто удалите обозначение, чтобы инициализаторы применялись к членам в порядке их объявления. Если инициализаторы не были в порядке объявления членов, то инициализаторы должны быть переупорядочены. В твоем случае:

{
    .Bar = Bar,
}
// becomes ->
{
    /*.Bar =*/ Bar,
}

Я использую С++

В C++ нет составных литералов. Они являются функцией C (начиная с C99).

Чтобы переписать его на C++, вам нужно использовать именованную переменную:

static Foo foo {
    Bar,
};
Foo *FooAPI = &foo;
person eerorika    schedule 07.01.2021