0

I have a program which looks like this

    // tuple example
    #include <iostream>     // std::cout
    #include <tuple>        // std::tuple, std::get, std::tie, std::ignore
    using namespace std;
    template <int i> class  xEnum
    {
    public:
        enum  val
        {
        x1,
        x2
        };
    };
    template <> class  xEnum<0>
    {
    public:
        enum val
        {
        RED,
        GREEN,
        WHITE
        };
    };
    template <> class  xEnum<1>
    {
    public:
        enum val
        {
        BANANA,
        ORANGE,
        APPLE
        };
    };

    class color:public xEnum<0>
    {
    public:
        static tuple<int, int, int> var;
        template< xEnum<0>::val i > static auto getVal()
        {
            return get<i>( var );
        }
    };
    tuple<int, int, int> color::var(10, 11, 12);

    class fruit:public xEnum<1>
    {
    public:

        static tuple<int, int, int> var;
        template< xEnum<1>::val i > static auto getVal()
        {
            return get<i>( var );
        }
    };
    tuple<int, int, int> fruit::var(20, 21, 22);
    template <int index> class variable:public xEnum<index>
    {
    public:
        static tuple<int, int, int> var;
        template< xEnum<index>::val i > static auto getVal()
        {
            return get<i>( var );
        }

    };
    int main ()
    {
      cout<<"Value is "<<color::getVal<color::RED>()<<endl;
      cout<<"Value is "<<color::getVal<color::GREEN>()<<endl;
      cout<<"Value is "<<color::getVal<color::WHITE>()<<endl;
      cout<<"Value is "<<fruit::getVal<fruit::BANANA>()<<endl;
      cout<<"Value is "<<fruit::getVal<fruit::ORANGE>()<<endl;
      cout<<"Value is "<<fruit::getVal<fruit::APPLE>()<<endl;

      return 0;
    }

This program compiles without any issues. Output of the program is

    $ g++ -Os -std=c++1y prog.cpp
    $ ./a.exe
    Value is 10
    Value is 11
    Value is 12
    Value is 20
    Value is 21
    Value is 22

Looking at the class color and fruit shows that they have a similar pattern. So I tried putting a generic class in place of the two classes, which looked like below

    template <int index> class variable:public xEnum<index>
    {
    public:
        static tuple<int, int, int> var;
        template< xEnum<index>::val i > static auto getVal()
        {
            return get<i>( var );
        }

    };

But with above template class I get compiler error below:

     error: 'xEnum::val' is not a type
         template< xEnum<index>::val i > static auto getVal()

Could someone please suggest a way to get rid of this compiler error or a way to define the two classes fruit and color in a generic way?

Thanks in advance.

Only way I could come up with is

    #define var_class(x, y)  class x:public xEnum<y> \
                             { \
                             public:  \
                                 static tuple<int, int, int> var; \
                                 template< xEnum<y>::val i > static auto getVal() \
                                 { \
                                     return get<i>( var ); \
                                 } \
                             }\

Above macro works, but I am not too keen on using macros to avoid repetition of code in c++. There should be some elegant c++ template solution to avoid this.

Ravi
  • 251
  • 2
  • 3
  • 11

0 Answers0