2
template < int ...Indices>

class T1 {
    template <int _1, int _2>
    class T2;
};

template <int ...Indices>
template <int _1>
class T1<Indices...>::T2<_1, sizeof...(Indices)> {};
//^--error: non-type template argument depends on a template parameter of the partial specialization

compiles on gcc 4.5+ but neither on clang 3.1 nor icc, both complaining about the usage of sizeof...(Indices). Is it just a not-yet implemented feature in the latter compilers or some special case?

Thanks,

Buote

1
  • 4
    Looks like a bug in those compilers. If you can, try defining the nested template inside T1's class {} block, perhaps delegating to a separate member template if necessary. Commented Jan 15, 2012 at 12:20

2 Answers 2

1

The standard says in [temp.class.spec] paragraph 8 that

Within the argument list of a class template partial specialization, the following restrictions apply:
— A partially specialized non-type argument expression shall not involve a template parameter of the partial specialization except when the argument expression is a simple identifier. [ Example:

    template <int I, int J> struct A {};
    template <int I> struct A<I+5, I*2> {};  // error
template <int I, int J> struct B {}; template <int I> struct B<I, I> {}; // OK
end example ]

The purpose of the rule is to disallow partial specializations based on non-trivial expressions like those in the example, and sizeof...(Indices) is not a simple identifier so maybe clang and ICC are right to reject it. I'm not sure which compiler is right, to be honest. I suggest reporting a bug to one of the compilers and if they say their implementation is correct report it to the others for interpreting it differently!

Sign up to request clarification or add additional context in comments.

Comments

0

You could attempt to try:

template < int ...Indices>
class T1 
{
    static const int index_size = sizeof...(Indices);

    template <int _1, int _2>
    class T2;
};

template <int ...Indices>
template <int _1>
class T1<Indices...>::T2<_1, T1<Indices...>::index_size> {};

and see if the compiler issue is with the actual sizeof... operator, or if it's with the way it's being used in the template declaration.

2 Comments

That doesn't work either, so I guess they're both lacking the feature at the moment - as a workaround i just reversed my initial recursion order so that the partial specialization could be done for a constant value (e.g. 1).
As a sidenote, the intel compiler has some weird issues sometimes with the specialization of nested classes - making the corresponding declaration necessary inside the outer class' {}; block instead of outside.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.