Consider this simple template specialization:
template<typename T, size_t I>
struct S {};
template<typename T>
struct S<T, std::tuple_size<T>::value> {};
GCC does not compile it, as it uses template parameter T
in the template argument std::tuple_size<T>::value
:
error: template argument 'std::tuple_size<_Tp>::value'
involves template parameter(s)
Now let's replace T
with typename std::remove_reference<T>::type
in tuple_size
template argument:
// Using primary structure template from previous example.
template<typename T>
struct S<T, std::tuple_size<typename std::remove_reference<T>::type>::value> {};
This code still uses template parameter in template argument, but GCC compiles it without any errors or warnings. Why?
Now if we try to compile the second example using MSVS with /std:c++latest
flag, it stops with error C2755:
non-type parameter of a partial specialization must be a simple
identifier
What is this strange restriction? I want to stop compile-time recursion when I
becomes equal to tuple size.
So who of them is wrong: MSVS or GCC?
Note that MSVS reports the error even without any template instantiations, while GCC works fine with all of these instances:
S<std::tuple<int, float>, 9> s1;
S<std::tuple<int, float>, 2> s2;
S<int, 42> s3;
I use MSVS Community 2015 Update 3 with it's default compiler and GCC 6.2.1.
Tried Clang 3.8.0. It does not compile both snippets with an error similar to GCC's message:
error: non-type template argument depends on a template parameter of
the partial specialization
See Question&Answers more detail:
os