1

Okay, after searching myself half to death and not finding any answer that actually seemed to work I gotta ask:

Say I've got a class (contrived example, but hopefully good enough for now)

template <typename T, std::enable_if_t< MyConditional<T>::value >>
class MyClass
{
public:
    static const MyClass ZeroInited;

    MyClass(int x, int y) 
        : m_X(x)
        , m_Y(Y) 
    {
    }

    ...
};

How do I properly initialize ZeroInited*? The correct syntax just eludes me (or maybe I'm just too tired), and letting tools "Create Implementation" does not produce correct output either. It's

Thanks everyone!

*) PS: in the templated case, not for a specialization. If I leave out the enable_if_t it's easy:

template <typename T> const MyClass<T> MyClass<T>::ZeroInited {0, 0};

but I can't figure out how to change it once enable_if_t comes into play.

Johann Studanski
  • 1,023
  • 12
  • 19

2 Answers2

3

If you can use C++17, you can declare ZeroInited inline and initialise it in the declaration (since this is then also a definition):

static const inline MyClass ZeroInited { 10, 20 };

Live demo

I'm not sure how you solve this in C++14 and earlier.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • That's of course a solution, but I try to keep my interfaces (as in class declarations, not the C# meaning) clean (pure declaration, no implementation), and put the implementations in an inl file. Thanks anyway, this is definitely a viable option. – Johann Studanski Jun 17 '20 at 22:02
3

Issue with

template <typename T, std::enable_if_t< MyConditional<T>::value >>

is that you expect as second argument a void value, which doesn't exist.

  • use

    template <typename T, std::enable_if_t< MyConditional<T>::value, bool> = false>
    class MyClass{/*..*/};
    

    and

    template <typename T, std::enable_if_t< MyConditional<T>::value, bool > B>
    const MyClass<T, B> MyClass<T, B>::ZeroInited{0, 0};
    

    Demo

  • or

    template <typename T, typename /*U*/ = std::enable_if_t< MyConditional<T>::value>>
    class MyClass{/*..*/};
    

    and

    template <typename T, typename U>
    const MyClass<T, U> MyClass<T, U>::ZeroInited{0, 0};
    

    Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302