Reputation: 273
I have the following code:
#include <utility>
template<class T,class E = void>
struct func_impl;
template<class T,class E = void>
constexpr inline bool has_func = false;
template<class T>
constexpr inline bool has_func<T,decltype(func_impl<T>::apply(std::declval<T>()))> = true;
template<>
struct func_impl<int>
{
static int apply(int i);
};
static_assert(has_func<int>);
The static_assert fails, where I expected it to succeed. What did I do wrong?
Upvotes: 4
Views: 167
Reputation: 172994
The problem is the default value of the 2nd template parameter E
comes from the primary template, it's void
and doesn't match the template parameter specialized in the specialization; which is specialized as decltype(func_impl<T>::apply(std::declval<T>()))
(i.e. int
in this case). Then the primary template but not specializatioin will be selected.
You could use std::void_t
.
template<class T>
constexpr inline bool has_func<T, std::void_t<decltype(func_impl<T>::apply(std::declval<T>()))>> = true;
// ^^^^^^^^^^^ ^
Upvotes: 6