Упростить шаблон has_field с помощью C ++ 17/20 - PullRequest
7 голосов
/ 12 марта 2020

Учитывая следующее рабочее решение:

template<typename T, typename = void>
struct has_value_t : std::false_type { };

template<typename T>
struct has_value_t<T, decltype(T::value, void())> : std::true_type { };

template<typename T>
constexpr bool has_value = has_value_t<T>::value;

Идея была взята из { ссылка }

Интересно, есть ли C ++ 17/20 больше лаконий c способ добиться того же эффекта. Как

template<typename T>
constexpr bool has_value = .....;

Использование:

template<typename T>
enable_if_t<has_value<T>,
std::ostream&> operator<<(std::ostream& os, T const& arg)
{
    return os << arg.value;
}

Ответы [ 2 ]

6 голосов
/ 12 марта 2020

Если C ++ 20 находится в таблице, вы можете сделать это с помощью концепции, которая проверяет простое требование

template <typename T>
concept has_value = requires(T) {
    T::value;
};

template<typename T> requires has_value<T>
std::ostream& operator<<(std::ostream& os, T const& arg)
{
    return os << arg.value;
}

T::value, будучи правильно сформированным выражением, проверяется в выражении require. Довольно просто написать и использовать в качестве ограничения для шаблона.

2 голосов
/ 12 марта 2020

In

template<typename,typename=void> constexpr bool has_value = false;
template<typename T>             constexpr bool has_value<T,decltype(T::value,void())> = true;

Тест

struct V { int value; };
struct W { int walue; };

static_assert(has_value<V>);
static_assert(not has_value<W>);

Благодаря { ссылка }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...