Reputation: 6230
It is possible to use the following pattern to detect whether or not x can be applied to T
template<class T, class Enable = void>
struct CanDoX: std::false_type{};
template<class T>
struct CanDoX<T, std::void_t<decltype(x(std::declval<T>()))>>:std::true_type{};
What if x
has been defined as
Foo const& x(Bar const&&) = delete;
Foo const& x(Bar const& val)
{return val.get();}
Now CanDoX<Bar>::value
is false
, because no overload accepts a temporary. Somehow, there has to be a Bar val
before the test for x(val)
.
Upvotes: 1
Views: 77
Reputation: 218238
std::declval<T>()
returns a T&&
so the better match is Foo const& x(Bar const&&)
.
but you can use lvalue reference inside std::declval
to get lvalue:
template<class T>
struct CanDoX<T, std::void_t<decltype(x(std::declval<T&>()))>>:std::true_type{};
or
template<class T>
struct CanDoX<T, std::void_t<decltype(x(std::declval<const T&>()))>>:std::true_type{};
Depending of your needs.
Upvotes: 0