序列元组
Tuple of sequence
本文关键字:元组 更新时间:2023-10-16
我想将一个类序列存储到一个元组中,并将该序列声明为另一个类的成员:
template<size_t id> class Foo {};
template<size_t N>
class FooContainer
{
std::tuple<Foo<0>, Foo<1>, ..., Foo<N>> tup; // build this type at compile time ??
};
我试过了:
template<size_t N>
class FooContainer
{
template<size_t... id>
struct FoosImpl {
constexpr FoosImpl(std::index_sequence<id...>) {};
using type = std::tuple<Foo<id>...>;
};
template<size_t N, typename Indices = std::make_index_sequence<N>>
using Foos = decltype(FoosImpl(Indices())::type);
Foos<N> tup;
};
但是这不会编译。GCC抱怨道:error: missing template arguments before ‘(’ token using Foos = decltype(FoosImpl(Indices())::type);
我认为编译器不需要指定模板,它会从Indices()
推断出整数序列。但事实似乎并非如此。
这是你想要做的一种可能的方法:
#include <tuple>
template<size_t id> class Foo {};
template <size_t... Idx>
std::tuple<Foo<Idx>...> get_foos(std::index_sequence<Idx...>);
template <size_t N>
using foo_tuple = decltype(get_foos(std::make_index_sequence<N>{}));
template<size_t N>
class FooContainer {
foo_tuple<N> tup;
};
你不能(目前)让编译器推断类模板参数(就像你在FoosImpl
中需要的那样),但你可以让它推断函数的模板参数并使用返回类型。
从您的示例开始,您可以这样做:
#include<tuple>
#include<utility>
#include<type_traits>
template<size_t id> class Foo {};
template<size_t N>
struct FooContainer
{
template<size_t... id>
static constexpr std::tuple<Foo<id>...> func(std::index_sequence<id...>) {}
using Foos = decltype(func(std::make_index_sequence<N>()));
Foos foos;
};
int main() {
static_assert(std::is_same<FooContainer<3>::Foos, std::tuple<Foo<0>, Foo<1>, Foo<2>>>::value, "!");
}
或者您可以简单地使用默认值为std::index_sequence<0,...,N>
的FooContainer的附加参数,如:
#include <utility>
#include <tuple>
#include <iostream>
#include <typeinfo>
template<size_t I> class Foo {};
template <size_t N, class = std::make_index_sequence<N>>
struct FooContainer;
template <size_t N, size_t... Is>
struct FooContainer<N, std::index_sequence<Is...>> {
using Foos = std::tuple<Foo<Is>...>;
Foos foos;
};
int main() {
std::cout << typeid(FooContainer<3>{}.foos).name() << std::endl;
}
输出:$ g++ -std=c++14 example.cc
$ ./a.out
St5tupleII3FooILm0EES0_ILm1EES0_ILm2EEEE
$ c++filt -t St5tupleII3FooILm0EES0_ILm1EES0_ILm2EEEE
std::tuple<Foo<0ul>, Foo<1ul>, Foo<2ul> >
编辑:正如skypjack提到的,现在可以通过显式传递第二个参数以意想不到的方式使用我们的FooContainer
类…如果不希望在FooContainer
的第二个参数中传递任意序列,可以通过添加static_assert来保护代码,如下所示:
#include <utility>
#include <tuple>
#include <iostream>
#include <typeinfo>
#include <type_traits>
template<size_t I> class Foo {};
template <size_t N, class = std::make_index_sequence<N>>
struct FooContainer;
template <size_t N, size_t... Is>
struct FooContainer<N, std::index_sequence<Is...>> {
static_assert(std::is_same<std::make_index_sequence<N>, std::index_sequence<Is...>>::value, "passed index_sequence was not generated using std::make_index_sequence<N>");
using Foos = std::tuple<Foo<Is>...>;
Foos foos;
};
int main() {
std::cout << typeid(FooContainer<3>{}.foos).name() << std::endl;
}
相关文章:
- C++:TypeDef使用元组
- Pybind11:将元组列表从Python传递到C++
- 重载元组索引运算符-C++
- 在C++中,如何通过几种类型从元组中选择多个元素
- 将fold表达式与std::一起用于两个元组
- std::ranges::elements_view,用于自定义类似元组的数据
- 将元组的向量转换/构造为堆
- 专用于 std 元组的模板,而无需用户执行remove_cvref
- 将元组的向量构造成堆
- 元组由 Swig 生成的 Python 包装器返回,用于C++向量
- 将元组类型扩展为可变参数模板?
- 时间复杂度 当具有复合数据类型(如元组或对)时?
- 类内部和外部静态 constexpr 元组之间的差异
- 可变参数模板与使用元组在参数中添加不同的数据对
- 访问和打印元组中的数据,并使用 C++14 使用模板函数显示数据
- boost::包含提升单元的元组的哈希值
- 我正在寻找一种优雅的方式来从元组向量创建tuple_element向量
- 如何在可变参数模板函数中遍历可变参数元组?
- 如何使用 SML 随机生成八进制元组
- 元组的运行时索引