FaTony FaTony - 1 month ago 23
C++ Question

static constexpr member initialization in header only library

I have found questions that are almost exactly as mine but I have 1 extra requirement - I need something that I can use as a default argument.

I'm writing a header only template library and I have a code like this:

#include <chrono>

template <typename T>
class Foo
{
public:
using Duration = std::chrono::duration<float>;
static constexpr Duration DefaultDuration{1.0f};
Foo(Duration duration = DefaultDuration)
: duration{duration}
{
}
private:
Duration duration;
};

int main(int argc, char* argv[])
{
Foo<int> foo;
}


As you can see, I can't use a function call because it wouldn't work as a default argument, right? Is there a solution?

Answer

The issue here does not appear to be the default parameter, but the initialization. By switching to the uniform initialization syntax, and explicitly declared the static class member, this compiles without issues, with gcc 6.2.1:

#include <chrono>

template <typename T>
class Foo
{
public:

    static constexpr std::chrono::duration<float> DefaultDuration{1.0f};

    Foo(std::chrono::duration<float> duration = DefaultDuration);
};

template<typename T>
constexpr std::chrono::duration<float> Foo<T>::DefaultDuration;

Foo<int> f;

int main()
{
    return 0;
}

gcc 6.2.1 actually lets you skate by without explicitly defining the static const member, but this is technically required, as explained here.

Comments