Обнаружение члена на основе пользовательской реализации void_t - PullRequest
0 голосов
/ 14 сентября 2018

У меня есть книга C ++ Templates, полное руководство, и я пытаюсь реализовать некоторые из описанных методов. Одним из них является обнаружение функции-члена, но моя реализация, похоже, не работает.

Я не могу использовать void_t, так как использую C ++ 11, но я скопировал определение, поэтому это не должно быть проблемой.

Следующий код:

namespace nt_detail
  {
  template< class... >
  using void_t = void;
  }

template<typename T, typename = nt_detail::void_t<>>
struct HasHelloMember
    : std::false_type {};

template<typename T>
struct HasHelloMember<T,
    nt_detail::void_t<decltype(std::declval<T>().hello())>>
       : std::true_type {};

и вот тестовый:

class ZZZ
  {

  };

class ZZZ2
  {
  public:
  void hello()
    {}
  };

int main()
  {
  if(HasHelloMember<ZZZ>::value)
    {
    std::cout << "ZZZ has hello" << std::endl;
    }
  else
    {
    std::cout << "ZZZ has NOT hello" << std::endl;
    }



if(HasHelloMember<ZZZ2>::value)
  {
  std::cout << "ZZZ2 has hello" << std::endl;
  }
else
  {
  std::cout << "ZZZ2 has NOT hello" << std::endl;
  }
}

В обоих случаях я получаю "привет". Возможно, что-то не так с моей реализацией void_t?

1 Ответ

0 голосов
/ 14 сентября 2018

Попробуйте это определение void_t, если вы не используете C ++ 17:

template<typename... Ts> struct make_void { typedef void type;};
template<typename... Ts> using void_t = typename make_void<Ts...>::type;

Согласно https://en.cppreference.com/w/cpp/types/void_t:

До CWG 1558 (дефект C ++ 14), неиспользуемые параметры в шаблонах псевдонимов не были гарантированы для обеспечения SFINAE и могут быть проигнорированы, поэтому раньше компиляторам требуется более сложное определение void_t, например

Это проблема с gcc до версии 5.1.

...