Non-trivially initializing static member of template class in C++11 without clang warnings

Viewed 271

I have a template class with a structure about as follows:

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

Now this seems to be the commonly recommended way to initialize a static member of a template class that can't be initialized trivially in its declaration. And with both VS 2015 and g++ it seems to work nicely.

However, clang doesn't agree, and issues a warning when the class is ultimately used:

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.

It is my understanding that this means I should add the following code to the header file:

extern template class MathFoo<float>;

and presumably the following to the cpp file:

template class MathFoo<float>;

but no matter where I put it, all this gives me is an outright error instead of the warning - either 'explicit specialization after instantiation' or 'explicit specialization after instantiation' 'explicit instantiation after specialization'.

I also tried to add an explicit instantiation declaration for just the member, but that didn't work either.

Any ideas?

C++17 is not an option for me, unfortunately; the code must be compatible with C++11.

1 Answers
Related