hynner
hynner

Reputation: 1352

C++ parameter pack fails to expand

I'm playing with variadic templates and I can't understand why the following code won't compile (GCC 4.9.2 with std=c++11):

It's just an example, but I need similar kind of use in my code and it fails as well:

template<int I>
class Type{};
template<typename ... Tlist>
class A{
    public:
        template<int ...N>
            void a(Type<N> ... plist){

            }
};
template<typename ... Tlist>
class B{
public:
    template<int ... N>
        void b(Type<N> ... plist){
            A<Tlist...> a;
            a.a<N...>(plist ...);
        }
};

And the use example:

B<int, int, int> b;
b.b<1,7,6>(Type<1>(),Type<7>(),Type<6>());

I get the following error:

file.cpp: In member function ‘void B<Tlist>::b(Type<N>...)’:
file.cpp:58:9: error: expected ‘;’ before ‘...’ token
    a.a<N...>(plist ...);
         ^
file.cpp:58:24: error: parameter packs not expanded with ‘...’:
    a.a<N...>(plist ...);
                        ^
file.cpp:58:24: note:         ‘N’

However the following code compiles fine (I just removed Tlist parameters from both classes and adjusted the code accordingly):

template<int I>
class Type{};
class A{
    public:
        template<int ...N>
            void a(Type<N> ... plist){

            }
};
class B{
public:
    template<int ... N>
        void b(Type<N> ... plist){
            A a;
            a.a<N...>(plist ...);
        }
};


B b;
b.b(Type<1>(),Type<7>(),Type<6>());

Can anyone give me an explanation? Thanks.

Upvotes: 1

Views: 136

Answers (1)

ecatmur
ecatmur

Reputation: 157354

The compiler has no reason to believe that a.a is a template; as such, it is mandated to interpret the < as the less-than operator. Write:

        a.template a<N...>(plist ...);
          ^^^^^^^^^

In your second example, it knows that a.a is a template, because the type of a there does not depend on a template parameter.

Upvotes: 3

Related Questions