如何递归元组
How do I recurse tuples?
我正在尝试制作一个可变参数模板容器,用于存储元素向量元组。这个容器的要点是所有向量的元素都是相关的,我想在以后保持这种相关性,但它对于计算不是必需的。想象一下,如果你愿意的话,某种类型的vector_3和ref_id。
容器只会将载体均匀地突变在一起。所以我理解的部分看起来像这样:
template<typename ...Elems>
class container
{
std::tuple<std::vector<Elems>...> data_;
public:
template<typename I>
const typename std::tuple_element<I, data_type>::type &nth_index() const
{ return std::get<I>(data_); }
};
我正在努力使用插入方法。我在想一些类似的事情:
void push_back(std::tuple<Elems...> &values)
{
std::tuple<std::back_insert_iterator<std::vector<Elems>>...> inserters;
}
但是我不知道如何初始化这个"插入器"元组。我一直在堆栈溢出上查看各种递归模板示例,我无法将其全部保留在脑海中足够长的时间来理解它。
我假设如果我有这样的元组,我可以使用简单的赋值:
inserters = values;
我还想在所有数组中编写一个返回值元组的访问器:
std::tuple<Elems &...> operator[](const size_t index)
{
...
}
但是再一次,我不知道如何初始化这个元组。
我不能是唯一一个想这样做的人,我找不到一个好的资源来学习它。与此同时,我正在尝试消化 0x 的原始可变参数模板提案。见解将不胜感激。我受到 MSVC 2012 实现的限制。
#include <vector>
#include <tuple>
#include <cstddef>
#include <utility>
template <typename... Elems>
class container
{
using data_type = std::tuple<std::vector<Elems>...>;
data_type data_;
public:
template <std::size_t I>
const typename std::tuple_element<I, data_type>::type& nth_index() const
{ return std::get<I>(data_); }
void push_back(const std::tuple<Elems...>& values)
{
return push_back(std::make_index_sequence<sizeof...(Elems)>{}, values);
}
std::tuple<Elems&...> operator[](std::size_t index)
{
return get_elems(std::make_index_sequence<sizeof...(Elems)>{}, index);
}
private:
template <std::size_t... Is>
void push_back(std::index_sequence<Is...>, const std::tuple<Elems...>& values)
{
using expand = int[];
static_cast<void>(expand{ 0, (std::get<Is>(data_).push_back(std::get<Is>(values)), 0)... });
}
template <std::size_t... Is>
std::tuple<Elems&...> get_elems(std::index_sequence<Is...>, std::size_t index)
{
return std::forward_as_tuple(std::get<Is>(data_)[index]...);
}
};
演示
具有
SFINAE 和类型特征的 C++11 解决方案:
template<typename ...Elems>
class container {
std::tuple<std::vector<Elems>...> data_;
template<std::size_t N>
typename std::enable_if<(N <std::tuple_size<decltype(data_)>::value), int>::type
push_back_impl(std::tuple<Elems...> const &values) {
std::get<N>(data_).push_back(std::get<N>(values));
return push_back_impl<N + 1>(values);
}
template<std::size_t N>
typename std::enable_if<(N == std::tuple_size<decltype(data_)>::value), int>::type
push_back_impl(std::tuple<Elems...> const &values) {
return 0;
}
public:
void push_back(std::tuple<Elems...> const &values) {
push_back_impl<0>(values);
}
};
现场演示
至于下标运算符,您需要在此SO答案中找到一些额外的机制:
template <size_t ...I>
struct index_sequence {};
template <size_t N, size_t ...I>
struct make_index_sequence : public make_index_sequence<N - 1, N - 1, I...> {};
template <size_t ...I>
struct make_index_sequence<0, I...> : public index_sequence<I...> {};
template<typename ...Elems>
class container {
std::tuple<std::vector<Elems>...> data_;
template<size_t ...I>
std::tuple<Elems&...> access_impl(std::size_t const idx, index_sequence<I...>) {
return std::tie(std::get<I>(data_)[idx]...);
}
public:
std::tuple<Elems&...> operator[](std::size_t const idx) {
return access_impl(idx, make_index_sequence<sizeof...(Elems)>());
}
};
现场演示
相关文章:
- 使用递归的数组的最小值.这是怎么回事
- 数组元素打印的递归方法
- 如何基于元组元素进行递归?
- 这是定义一组递归规则的正确方法吗?
- 如何使用 Boost Hana 删除元编程递归
- 使用元编程递归初始化 std::array
- 为模板中的元组创建递归函数
- 以先前的通话递归致电每个元组成员
- 递归地构建元组
- 模板元编程递归上限
- C++排序数组递归
- C++元编程递归步长限制
- 如何递归元组
- 用C++14索引序列可以改进元组变元模板递归吗
- 重载成员函数访问元组和递归累加结果失败的原因
- 模板递归区分boot::元组中的数据类型
- 对一个对象上的每个元组元素调用函数,不进行递归
- 通过除数组递归地计算和
- 在元组上操作的递归可变模板方法
- 动态数组递归与不同的编译器