1

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).

user877329
  • 6,717
  • 8
  • 46
  • 88

1 Answers1

0

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.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
Jarod42
  • 203,559
  • 14
  • 181
  • 302