Is `void_t` necessary to check if a class has a method with a specific signature?

When I first learned how to verify a particular signature in a class, I was taught how to use std::void_tand write code like this:

template<typename T, typename =void>
class HAS:public false_type{};

template<typename T>
class HAS<T,void_t<decltype(declval<T>().print())>>:public true_type{};

And this piece of code checks to see if the class has a method named " print()". It works well.

But when I tried to remove std::void_t, it still worked.

The code is as follows:

template<typename T, typename = void>
class HAS:public false_type{};

template<typename T>
class HAS<T,decltype(declval<T>().print())>:public true_type{};

So, I'm confused if " std::void_t" you need to check if the class has a method with a specific signature? Or is it just a coincidence?

+4
source share
3 answers

, void_t ( ). , , void.

, print() void, decltype(declval<T>().print()) . print() - , bool, .

+10

"void_t" , ?

+1 ; : std::void_t , ( ) .

decltype(std::declval<T>().print(), void())

( ++ 11 ; std::void_t ++ 17)

struct foo
 { };

struct bar
 { int print () const { return 0; } };

template <typename T, typename = void>
class HAS
   : public std::false_type
 { };

template <typename T>
class HAS<T, decltype(std::declval<T>().print(), void())>
   : public std::true_type
 { };

int main ()
 {
   static_assert( HAS<foo>::value == false, "!" );
   static_assert( HAS<bar>::value == true,  "!!" );
 }
+4

, , <std::void_t

, . SFINAE, void_t, . , void_t, .

, ++ 17 is_detected, std::experimental. . .

#include <experimental/type_traits>

template < typename T >
using print_t = decltype(std::declval<T>().print());

template < typename T >
using has_print = std::experimental::is_detected< print_t, T >;

struct A {};

struct B { void print() {} };

int main()
{
  static_assert( has_print<A>::value == false );
  static_assert( has_print<B>::value == true  );
}

0

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


All Articles