元组作为 C++ 中的模板

Tuples as templates in c++

我得到了一个类型元组(例如 std::tuple),我想创建由这些类型给出的向量组成的元组。我写了这个,但是当我想用它的时候,它不起作用,我得到这个错误:

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

我对可变参数模板还很陌生,所以我不知道如何正确操作。

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;
}

你的第一个模板参数是模板模板参数,但是types不是模板,它是类型。另外,您的 ... 放错了地方。您需要 tuple<vector<Types>...>,否则 Types 将作为 vector.

的参数展开

以下带有免责声明:我知道一些 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

在您的代码中,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;
}

从你的问题来看,你的需求似乎只是为了能够方便的表达类型

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

作为

vertices<tuple<int, string, double>>

这可以使用变量模板来实现。我们所需要的只是获取一个类型(即一个元组),并将该元组解压缩到一个向量中。由于类型不是可变参数包,我们需要另一个间接级别来获取元组中的类型。 @NathanOliver 的回答展示了一种很好的方法,即使用函数模板的声明。正如所指出的,由于我们只需要类型转换,函数不需要定义,声明说明了一切:参数类型是输入类型,return 类型是输出类型。

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>>>{});