Кортежи как шаблоны в c ++ - PullRequest
0 голосов
/ 09 апреля 2020

Я получаю кортеж типов (например, std :: tuple) и хочу создать кортеж векторов, заданных этими типами. Я написал это, но когда я использую его как хочу, он не работает, я получаю эту ошибку:

Error (active)  E0730   type "types" is not a class template

Я довольно новичок в шаблонах variadi c, поэтому я не знаю, как сделать это правильно.

using namespace std;

template <template <typename...> typename Tuple, typename... Types>
class vertices
{
public:
    tuple<vector<Types...> > v;
};

int main{
    using types = tuple<int, string, double>;

    vertices<types> ver;
}

Ответы [ 3 ]

2 голосов
/ 10 апреля 2020

В вашем коде Tuple - это параметр шаблона шаблона, поэтому он ожидает шаблон. types это не шаблон, а конкретный тип, поэтому его нельзя использовать. Вместо этого вы можете просто взять кортеж, а затем с помощью вспомогательной мета-функции получить тип для члена, например

// no definition since it is only used in unevaluated contexts, just used as a helper to get the type converted
template <typename... Types> 
std::tuple<std::vector<Types>...> tuple_to_tuple_of_vectors(std::tuple<Types...>);

template <typename Tuple>
class vertices
{
public:
    using tuple_type = decltype(tuple_to_tuple_of_vectors(std::declval<Tuple>()));
    tuple_type v;
};

int main ()
{
    using types = tuple<int, string, double>;

    vertices<types> ver;
}
1 голос
/ 10 апреля 2020

Судя по вашему вопросу, ваше требование состоит в том, чтобы просто иметь возможность express тип

tuple<vector<int>, vector<string>, vector<double>>

как

vertices<tuple<int, string, double>>

Это может быть достигнуто с помощью переменного шаблона , Все, что нам нужно, это взять тип (это кортеж) и распаковать этот кортеж в вектор. Поскольку тип не является пакетом variadi c, нам необходим другой уровень косвенности для получения типов в кортеже. Ответ @ NathanOliver показывает хороший способ сделать это, используя объявление функции-шаблона. Как уже указывалось, поскольку все, что нам нужно, - это преобразования типов, функция не нуждается в определении, объявление говорит само за себя: тип аргумента - это тип ввода, а тип возврата - тип вывода.

template <typename... Types>
auto unpack(tuple<Types...>) -> tuple<vector<Types>...> ;

template <typename Tuple>
using vertices = decltype(unpack(declval<Tuple>())); 

static_assert(std::is_same<
                  vertices<tuple<int, string, double>>,
                  tuple<vector<int>, vector<string>, vector<double>>>{});
0 голосов
/ 09 апреля 2020

Ваш первый параметр шаблона - это параметр шаблона шаблона, но types - это не шаблон, это тип. Также у вас есть ... в неправильном месте. Вам нужно tuple<vector<Types>...>, в противном случае Types раскрывается как параметры для vector.

Следующее идет с заявлением об отказе: я знаю немного tempaltes с C ++ 11, но я довольно не осведомлен о новые функции, так что могут быть более элегантные способы написать то же самое.

В качестве базового шаблона вы можете использовать:

template <typename... Types>
struct vertices
{
    using tuple_of_vectors_t = tuple<vector<Types>... >;
    tuple_of_vectors_t v;
};

А затем для кортежей:

template <typename... Types>
struct vertices<std::tuple<Types...>> : vertices<Types...> {};

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

#include <tuple>
#include <vector>
#include <iostream>
#include <type_traits>
using namespace std;

template <typename... Types>
struct vertices
{
    using tuple_of_vectors_t = tuple<vector<Types>... >;
    tuple_of_vectors_t v;
};

template <typename... Types>
struct vertices<std::tuple<Types...>> : vertices<Types...> {};


int main () {
    using types = tuple<int, string, double>;

    vertices<types> ver;
    std::cout << std::is_same_v< vertices<types>::tuple_of_vectors_t, 
                                 std::tuple< std::vector<int>, 
                                             std::vector<std::string>,
                                             std::vector<double>
                                           >
                                >;
}

Вывод:

1
...