元组作为 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>>>{});
我得到了一个类型元组(例如 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>>>{});