std :: void_t и вложенные не типовые члены - PullRequest
0 голосов
/ 29 августа 2018

У меня есть следующий код, где я получаю неожиданный результат (второй static_assert не удается):

#include <type_traits>

template <typename T, typename = void>
struct is_bananas : std::false_type {};
template <typename T>
struct is_bananas<T, std::void_t<typename T::config::num_items>>
    : std::true_type {};

struct Config{
    static constexpr int num_items=42;
};

struct Bananas{
    using config = Config;
};

static_assert(is_bananas<int>::value == false);
static_assert(is_bananas<Bananas>::value == true);

Когда я использую T::config вместо T::config::num_items, код работает как положено.

Если я использую decltype вокруг num_items, то это работает.

Правильно ли предположить, что void_t работает только с типами?

Есть ли лучший способ сделать то, что я хочу?
Если кого-то смущает это (и подумайте: просто бросьте decltype) - я нахожу decltype трудным для чтения в реальном коде, когда есть длинные имена и глубокое вложение, поэтому, если есть лучший способ сделать это с void_t или любой другой код шаблона, который я хотел бы знать.

1 Ответ

0 голосов
/ 29 августа 2018

Есть ли лучший способ сделать то, что я хочу?

Приятно и приятно субъективно.

К примеру, я нахожу очень милым ваше решение decltype().

В любом случае ... возможной альтернативой является определение замены std::void_t, которая работает с типами значений

Что-то как

template <auto...>
using value_void_t = void;

и напишите

template <typename T>
struct is_bananas<T, value_void_t<T::config::num_items>>
   : std::true_type {};
...