Reputation: 42379
#include <type_traits>
using namespace std;
struct A
{
using key_type = int;
};
template<typename T, typename = void>
struct has_key_type : false_type
{};
template<typename T>
struct has_key_type<T, decltype(typeid(typename T::key_type), void())>: true_type
{};
int main()
{
cout << has_key_type<A>::value << endl;
cout << has_key_type<int>::value << endl;
}
The output is:
1
0
Which is as expected. However, if I change from
decltype(typeid(typename T::key_type), void())
to
decltype(typeid(typename T::key_type), int())
as follows:
template<typename T>
struct has_key_type<T, decltype(typeid(typename T::key_type), int())>: true_type
{};
The output is:
0
0
Why does the second version not work?
Upvotes: 3
Views: 73
Reputation: 13040
You did not give the second template argument, so it will use the default template argument, which is void
. In your second version, the type of decltype(typeid(typename T::key_type), int())
is int
, so has_key_type<A>
, which is equivalently has_key_type<A, void>
, will certainly not match this partial specialization.
BTW, since C++17, you can use std::void_t
to simplify decltype(typeid(typename T::key_type), void())
to std::void_t<typename T::key_type>
.
Upvotes: 4