Is there a way to get the negation of whether a function exists for an object?

To determine if a function exists for a function, you can use the following:

template <typename...Ts>
using void_t = void;

void fn(int);

struct X {};

template <typename T, typename = void_t<decltype(fn(std::declval<T>()))>>
void fn2(T) { }

void test() {
  fn2(int(1)); // works
  //fn2(X()); // doesn't work
}

Now, is there a way to determine if a fn(T)type exists T?

Example:

void test2() {
  //fn2(int(1)); // doesn't work
  fn2(X()); // works
}

The reason for this is to define an exception operation so that I can define fn2()in order to avoid an ambiguity error.

+4
source share
2 answers

The usual way to do this is to do a type trait, as @chris said:

template <typename T, typename = void>
struct fn_callable_with : std::false_type {};
template <typename T>
struct fn_callable_with<T, void_t<decltype(fn(std::declval<T>()))>> : std::true_type {};

// For bonus C++14 points:
// template <typename T>
// /*C++17: inline*/ constexpr bool fn_callable_with_v = fn_callable_with<T>::value;

template <typename T, typename = typename std::enable_if<!fn_callable_with<T>::value>::type>
// C++14: template <typename T, typename = std::enable_if_t<!fn_callable_with_v<T>>>
void fn2(T) { }
+4
source

You need another overload fn2, otherwise SFINAE will not do anything useful.

void fn2(...) { } // called if the overload below is SFINAEd away

template <typename T, typename = void_t<decltype(fn(std::declval<T>()))>>
void fn2(T) { }

live example in wandbox


, SFINAE . fn2 , .

+1

Source: https://habr.com/ru/post/1688221/


All Articles