Нетривиальная инициализация статического члена класса шаблона в C ++ 11 без предупреждений лязга - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть шаблон класса со структурой примерно следующим образом:

foobar.h:

class Bar
{
    Bar(float f);
};

template<typename T>
class Foo
{
    Foo(const Bar&);
    ...
    static const Foo mkFooConst;
};

typedef Foo<float> MathFoo;

foobar.c:

template<> const MathFoo MathFoo::mkFooConst(Bar(0.815));

Теперь, кажется, это наиболее рекомендуемый способ инициализации статического члена класса шаблона, который не может быть тривиально инициализирован в его объявлении. И как с VS 2015, так и с g ++ это, кажется, работает хорошо.

Однако clang не соглашается и выдает предупреждение, когда класс в конечном итоге используется:

warning: instantiation of variable 'Foo<float>::mkFooConst' required
here, but no definition is available [-Wundefined-var-template]
...
note: add an explicit instantiation declaration to suppress this
warning if 'Foo<float>::mkFooConst' is explicitly instantiated in
another translation unit.

Насколько я понимаю, это означает, что я должен добавить следующий код в заголовочный файл:

extern template class MathFoo<float>;

и предположительно следующее для файла cpp:

template class MathFoo<float>;

но независимо от того, где я это поместил, все это дает мне прямую ошибку вместо предупреждения - либо «явная специализация после создания экземпляра», либо «явная специализация после создания экземпляра» «явное создание экземпляра после специализации» .

Я также пытался добавить явное объявление экземпляра только для члена, но это тоже не сработало.

Есть идеи?

C ++ 17 для меня не вариант, к сожалению; код должен быть совместим с C ++ 11.

1 Ответ

0 голосов
/ 07 сентября 2018

Вы должны поставить:

template<> const MathFoo MathFoo::mkFooConst;
// Declaration only, mkFooConst{} would be a definition.

Демо с несколькими файлами

Нет предупреждения с лязгом

...