Not picking template partial specialization?

http://ideone.com/ChET01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <type_traits>

template<typename T, typename = void>
struct Test
{
	static int constexpr value = 1;
};
template<typename T>
struct Test
<
	typename std::enable_if
	<
		std::is_integral<T>::value,
		T
	>::type, T
>
{
	static int constexpr value = 2;
};

int main()
{
	std::cout << Test<short>::value << std::endl;
}
1
Why does it output 1 instead of 2? How can I make it output 2 and still output 1 for e.g. Test<double>::value?
Last edited on
In template< typename T, typename = void > struct Test, the enabler is the second template parameter.
And it defaults to void.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <type_traits>

template< typename T, typename = void > struct test
     : std::integral_constant<int,1> {} ;

template < typename T >
struct test< T, typename std::enable_if< std::is_integral<T>::value, void >::type >
     :  std::integral_constant<int,2> {} ;

int main()
{
    std::cout << "short: " << test<short>::value << '\n'
              << "double: " << test<double>::value << '\n' ;
}

http://coliru.stacked-crooked.com/a/59fd9173a944b6a7
Interesting, could you explain why it works that way?
With template< typename T, typename = void > struct test as the generalization,

when the compiler sees test<short>, it knows that test<short,void> is to be instantiated.
If a specialization that matches test<short,void> is not seen, it instantiates the generalization.
Topic archived. No new replies allowed.