c++templates

Accessing static member of nested template class


I have a templated class (Outer) and want to create a nested template class based on an enum of the class. This inner class has static variables, so they will need to be defined outside of the class to be accessible.

template <class T>
class Outer
{
private:
  enum InnerType {foo, bar /* etc */};
  
  template <InnerType U>
  class Inner
  {
  public:
    static int x;
  };

public:
  // access Inner<>::x
  void print() { std::cout << Inner<foo>::x << std::endl; }
};

// somehow define Inner<>::x

I've tried multiple different variations on the syntax in the accepted answer here but I can't seem to get it working. It compiles if I replace the enum with a class for each value, but the enum is much more explicit. Is it possible to use an enum here?


Solution

  • so they will need to be defined outside of the class

    That is not necessarily true. With c++17 we can use inline to provide the definition inside the class template as shown below.

    If you're using pre-c++17 standard, see the first solution. Note the use of the enum keyword in pre-c++17.

    So there are two ways to solve this depending on the c++ standard you're using as shown below.

    Pre C++17

    Here we provide an out-of-class definition:

    //-------------------------vvvv---------------------------->note this enum keyword
    template<class T> template<enum Outer<T>::InnerType I>  int Outer<T>::template Inner<I>::x =0;
    

    Working demo


    C++17

    You we can use inline to provide the definition inside the class.

    template <class T>
    class Outer
    {
    private:
      enum InnerType {foo, bar /* etc */};
      
      template <InnerType U>
      class Inner
      {
      public:
    //--vvvvvv-------------------->with c++17
        inline static int x = 0;
      };
    //other code as before
    };