gpt4 book ai didi

c++11 - 融合改编的 std_tuple View ,转换为另一个元组

转载 作者:行者123 更新时间:2023-12-02 23:59:49 25 4
gpt4 key购买 nike

Boost Fusion 的设计方式使得大多数转换都是“惰性的”,即它们都生成“ View ”而不是实际的(Fusion)容器( http://www.boost.org/doc/libs/1_58_0/libs/fusion/doc/html/fusion/algorithm.html )。例如,要实际反转向量,需要使用转换函数 as_vector ( http://www.boost.org/doc/libs/1_58_0/libs/fusion/doc/html/fusion/container/conversion/functions.html )。

boost::fusion::vector<int, double, std::string> vec;
auto view_rev = boost::fusion::reverse(vec); // view object
auto vec_rev = boost::fusion::as_vector(view_rev);

现在,我想用改编的 std::tuple 来做到这一点:

#include<boost/fusion/adapted/std_tuple.hpp>
...
std::tuple<int, double, std::string> tup;
auto view_rev = boost::fusion::reverse(tup);
auto tup_rev = boost::fusion::???(view_rev); // type should be of type std::tuple<std::string, double, int>

如何将结果 View 转换回元组?

我期望这个???函数被称为as_std_tuple(类似于boost::fusion::as_vector,但它没有不存在(还?)。

有一些用于反转元组的解决方案,在本例中我只想使用 Boost Fusion 中已有的解决方案。

最佳答案

我不知道有任何内置方法可以将 Boost Fusion Sequence 转换为 std::tuple,但使用 indices trick它可以很容易地实现:

template <std::size_t... Is>
struct indices {};

template <std::size_t N, std::size_t... Is>
struct build_indices
: build_indices<N-1, N-1, Is...> {};

template <std::size_t... Is>
struct build_indices<0, Is...> : indices<Is...> {};

template<typename Sequence, std::size_t ...Is>
auto as_std_tuple_impl(const Sequence& s, indices<Is...>&&) -> decltype(std::tie(boost::fusion::at_c<Is>(s)...))
{
return std::tie(boost::fusion::at_c<Is>(s)...);
}

template <typename Sequence, typename Indices = build_indices<boost::fusion::result_of::size<Sequence>::value>>
auto as_std_tuple(const Sequence& s) -> decltype(as_std_tuple_impl(s, Indices()))
{
return as_std_tuple_impl(s, Indices());
}

这是一个完整的示例,它使用 boost::fusion::reverse 反转改编的 std::tuple 并将其转换回 std::tuple 并打印两个元组:

#include <tuple>
#include <utility>

#include<boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/algorithm/transformation/reverse.hpp>
#include <boost/fusion/include/reverse.hpp>

#include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/include/size.hpp>

#include <iostream>

template <std::size_t... Is>
struct indices {};

template <std::size_t N, std::size_t... Is>
struct build_indices
: build_indices<N-1, N-1, Is...> {};

template <std::size_t... Is>
struct build_indices<0, Is...> : indices<Is...> {};

template<typename Sequence, std::size_t ...Is>
auto as_std_tuple_impl(const Sequence& s, indices<Is...>&&) -> decltype(std::tie(boost::fusion::at_c<Is>(s)...))
{
return std::tie(boost::fusion::at_c<Is>(s)...);
}

template <typename Sequence, typename Indices = build_indices<boost::fusion::result_of::size<Sequence>::value>>
auto as_std_tuple(const Sequence& s) -> decltype(as_std_tuple_impl(s, Indices()))
{
return as_std_tuple_impl(s, Indices());
}


template<class Tuple, std::size_t N>
struct TuplePrinter
{
static void print(const Tuple& t)
{
TuplePrinter<Tuple, N-1>::print(t);
std::cout << ", " << std::get<N-1>(t);
}
};

template<class Tuple>
struct TuplePrinter<Tuple, 1>
{
static void print(const Tuple& t)
{
std::cout << std::get<0>(t);
}
};

template<class... Args>
void print(const std::tuple<Args...>& t)
{
std::cout << "(";
TuplePrinter<decltype(t), sizeof...(Args)>::print(t);
std::cout << ")\n";
}

int main()
{
std::tuple<int, double, std::string> tup(1,2.5,"hello");
auto view_rev = boost::fusion::reverse(tup);
auto reversed_tup = as_std_tuple(view_rev);

print(tup);
print(reversed_tup);
return 0;
}

输出:

(1, 2.5, hello)
(hello, 2.5, 1)

Live example on ideone

关于c++11 - 融合改编的 std_tuple View ,转换为另一个元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31641296/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com