Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partial specialization for variadic template needs first non-variadic template parameter

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?

like image 895
Toby Brull Avatar asked Aug 11 '13 14:08

Toby Brull


1 Answers

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).

like image 166
Columbo Avatar answered Oct 27 '22 00:10

Columbo