Как принудительно инициализировать статический элемент ?

Рассмотрим этот пример кода:

template
char register_(){
    return D::get_dummy(); // static function
}

template
struct Foo{
    static char const dummy;
};

template
char const Foo::dummy = register_();

struct Bar
    : Foo
{
    static char const get_dummy() { return 42; }
};

( Также на Ideone .)

Я бы ожидал, что фиктивный будет инициализирован, как только появится конкретный экземпляр Foo , который у меня есть с Bar . Этот вопрос (и стандартная цитата в конце) довольно ясно объясняет, почему этого не происходит.

[...] в частности, инициализация (и любые связанные побочные эффекты) статического элемента данных не происходит, если сам статический элемент данных не используется таким образом, который требует определения статического члена данных для

Есть ли способ принудительно инициализировать фиктивный (фактически вызывая register_ ) без любого экземпляра Bar или Foo (без экземпляров, значит, без обмана конструктора) и без необходимости явно указывать член каким-либо образом пользователю Foo ? Дополнительные файлы cookie, чтобы производный класс ничего не делал.


Изменить : Нашел способ с минимальным влиянием на производный класс:

struct Bar
    : Foo
{   //                              vvvvvvvvvvvv
    static char const get_dummy() { (void)dummy; return 42; }
};

Хотя, мне все равно нужен производный класс не нужно этого делать. : |

20
задан Community 23 May 2017 в 11:46
поделиться

1 ответ

Мы можем использовать простой прием на основе объявления, которое нужно инстанцировать с классом:

template<…>
struct Auto {
  static Foo foo;
  static_assert(&foo);
};
template<…> Foo Auto::foo=…;

Примечание, которое некоторые компиляторы предупреждают о сравнении с пустым указателем; этого можно избежать с &foo==&foo в случае необходимости.

Примечание также, что количество GCC 9 doesn’t это как odr-использование .

1
ответ дан 30 November 2019 в 01:29
поделиться
Другие вопросы по тегам:

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