2

I have a problem which seems to be already discussed here in: CPP templated member function specialization

But the solution with this->template did not work with my example.

The following code fails with:

error: invalid operands of types '<unresolved overloaded function type>' and 'int'
       to binary 'operator<'

with gcc 4.8.1

class Base { public: virtual int Do(){return 0;} };
class State1: public Base {};
class State2: public Base {};

template <typename ... T> class SM;

template <class StateBase, class HeadState, class ... States >
class SM<StateBase, HeadState, States...> : public SM< StateBase, States...>
{
    protected:
        HeadState headState;
        template<int cnt> StateBase* GetNextState ( unsigned int index ) { return headState; }
};  

template <class StateBase, class HeadState>
class SM< StateBase, HeadState>
{
    protected:
        HeadState headState;
        template<int cnt> StateBase* GetNextState ( unsigned int index ) { return headState; }
};  

template <class StateBase, class ... States >
class TopSM: public SM< StateBase, States...>
{
    public:
        void DoIt()
        {
            // following code fails with 
            // error: invalid operands of types '<unresolved overloaded function type>' and 'int' to binary 'operator<'
            int nextState = this->template SM< StateBase, States...>::GetNextState <1>( 1 );
        }
};  

TopSM<Base, State1, State2> sm;

int main()
{
    sm.DoIt();
    return 0;
}
Community
  • 1
  • 1
Klaus
  • 24,205
  • 7
  • 58
  • 113
  • I made an [online compilable example of your code](http://coliru.stacked-crooked.com/view?id=94867f9e2864648d4555a3bc8c79cefa-f674c1a6d04c632b71a62362c0ccfc51) for easy reference. – Tony The Lion Aug 07 '13 at 08:36
  • Yes, this question is discussed multiple times here. Thank you for the link to this answer! – Klaus Aug 07 '13 at 08:51

2 Answers2

5

You need another template before GetNextState. If there are template arguments after an identifier and a ., ->, or :: before, and it's a member of something dependent on a template parameter, there needs to be a template keyword to disambiguate the less-than sign.

int nextState = this->template SM< StateBase, States...>::template GetNextState <1>( 1 );
Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
2

Almost there, you need another template

int nextState = this->template SM< StateBase, States...>::template GetNextState <1>( 1 );
                                                          ~~~~~~~~

The problem is that, because GetNextState comes from a template parameter, it doesn't know whether it's a static variable, function, template function or anything. The parser needs to continue, so it makes the assumption that its not a template function, so the < is parsed as a less-than operator, instead of the beginning of a template parameter list. From there, the parser gets confused and you get the error about invalid operands to >.

Peter Alexander
  • 53,344
  • 14
  • 119
  • 168