The following code
#include <iostream>
#include <utility>
template<typename F, typename... T>
struct Wrapper{ };
template<typename T>
struct is_wrapper : std::false_type {};
template<typename... T>
struct is_wrapper<Wrapper<T...>> : std::true_type {};
//template<typename F, typename... T>
//struct is_wrapper<Wrapper<F, T...>> : std::true_type {};
int main()
{
Wrapper<int, double> w;
std::cout << is_wrapper<decltype(w)>::value << std::endl;
}
prints 0. However, if one uncomments the two lines in the middle it prints 1.
Why doesn't it always print 1? Shouldn't the second partial specialization also cover the case which is apparently only covered by the third (commented) partial specialization?
The code should indeed match the partial specialization; The standard never actually disallowed this, but compilers did take a while to implement variadic templates and their deduction properly. GCC conforms since 4.9.0 and Clang as of 3.6. The relevant bug report for Clang is #22191 (I cannot find GCC's, though).