Передайте внутренний класс шаблона как аргумент шаблона в C ++ - PullRequest
0 голосов
/ 19 февраля 2020

Я пытаюсь передать внутренний класс шаблона (обычного класса) другому классу, который принимает шаблоны в качестве аргументов.

Класс, который принимает шаблоны:

template <typename... T> struct TypeList {
  template <template <typename...> typename P> using Apply = P<T...>;
};

Так когда у меня есть что-то вроде using List = TypeList<int, float, double>;, я могу сделать

static_assert(std::is_same<List::template Apply<std::tuple>,
                           std::tuple<int, float, double>>::value);

Но если я изменю std::tuple на внутренний шаблонный класс, он перестает работать. То есть

struct Outer {
  template <typename... P> struct Inner {};
};

static_assert(std::is_same<List::template Apply<typename Outer::Inner>,
                           Outer::Inner<int, float, double>>::value);

не работает.

Мой компилятор жалуется на

ошибку: недопустимое использование имени шаблона 'Outer :: Inner' без список аргументов

Это работает, если я "сглаживаю" внутренний класс шаблона с помощью template <typename... P> using Flat = Outer::Inner<P...>;.

Мой вопрос, есть ли способ заставить работать внутренний класс шаблона, без совмещения и выравнивания? Я пропускаю где-нибудь ключевое слово typename или template?

Полный пример:

#include <tuple>
#include <type_traits>

template <typename... T> struct TypeList {
  template <template <typename...> typename P> using Apply = P<T...>;
};

struct Outer {
  template <typename... P> struct Inner {};
};

template <typename... P> using Flat = Outer::Inner<P...>;

int main() {
  using List = TypeList<int, float, double>;
  static_assert(std::is_same<List::template Apply<std::tuple>,
                             std::tuple<int, float, double>>::value);
  static_assert(std::is_same<List::template Apply<Flat>,
                             Outer::Inner<int, float, double>>::value);
  static_assert(std::is_same<List::template Apply<typename Outer::Inner>,
                             Outer::Inner<int, float, double>>::value);
}

1 Ответ

2 голосов
/ 19 февраля 2020

typename Outer::Inner неверно, так как Inner - это не тип, а шаблон.

Вы даже можете удалить все имя типа / шаблона здесь, поскольку нет проблем с зависимым типом.

static_assert(std::is_same<List::Apply<Outer::Inner>,
                           Outer::Inner<int, float, double>>::value);

В зависимом контексте это будет

// template <typename OuterT> /*..*/
static_assert(std::is_same<List::Apply<OuterT::template Inner>,
                           typename OuterT::template Inner<int, float, double>>::value);

Демо

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