user877329
user877329

Reputation: 6230

SFINAE to detect operation when it is forbidden to call with temporary

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

Answers (1)

Jarod42
Jarod42

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

Related Questions