0

I don't understand why the following code doesn't compile:

template< typename TypeArg >
class Data
{
public:
    struct Selector1
    {
    };

    template< typename Selector >
    void foo()
    {
    }
};

template< typename TypeArg >
class Test
{
public:
    void test();
};


template< typename TypeArg >
void Test< TypeArg >::test()
{
    Data< TypeArg > data;
    data.foo< typename Data< TypeArg >::Selector1 >();
}

I have tested it with GCC 4.6 and GCC 4.9. Both give me the same error:

test.cpp: In member function »void Test::test()«: test.cpp:28:51: Error: expected »(« before »>« token test.cpp:28:53: Error: expected primary-expression before »)« token

Can somebody tell me what needs to be done for the code to compile?

theV0ID
  • 4,172
  • 9
  • 35
  • 56

1 Answers1

5

Since the type of data is dependent, the nature of data.foo is not known and needs to be disambiguated:

data.template foo<typename Data< TypeArg >::Selector1>();
//   ^^^^^^^^
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Thanks, that works. But why is this required? Isn't it obvious to the compiler that the type of `data` is dependent and `data.foo` is unknown? – theV0ID Mar 28 '15 at 15:32
  • 1
    @theV0ID: Of course, but what isn't obvious is what you want `foo` to be: a value, a type, or a template. Because that's unknown. So you need to specify. – Kerrek SB Mar 28 '15 at 15:33
  • In other words, is the `<` following `foo` opening a template parameter list, or is it the less-than operator? – T.C. Mar 29 '15 at 02:57
  • @T.C. Its a template parameter list. – theV0ID Mar 29 '15 at 11:59
  • 1
    @theV0ID: We know that *you* know that. But the problem is creating a language construct with an unambiguous meaning. That's done by requiring explicit disambiguation for dependent names. – Kerrek SB Mar 29 '15 at 12:10
  • @KerrekSB Ah, I see. – theV0ID Mar 29 '15 at 19:32