【问题标题】:Using std::get and std::tie on boost tuples, zip_iterator, etc在 boost 元组、zip_iterator 等上使用 std::get 和 std::tie
【发布时间】:2014-05-04 18:06:12
【问题描述】:

std::get<>()std::tie<>() 与boost 构造一起使用有哪些选择?

示例: 我想使用基于范围的 for 循环在多个容器上进行迭代。我可以实现zip函数,它使用boost::zip_iterator

 #include <boost/iterator/zip_iterator.hpp>
 #include <boost/range.hpp>

 template <typename... TContainer>
 auto zip(TContainer&... containers) -> boost::iterator_range<boost::zip_iterator<decltype(boost::make_tuple(std::begin(containers)...))>> {
    auto zip_begin = boost::make_zip_iterator(boost::make_tuple(std::begin(containers)...));
    auto zip_end = boost::make_zip_iterator(boost::make_tuple(std::end(containers)...));
    return boost::make_iterator_range(zip_begin, zip_end);
 }

现在我可以这样使用它了:

std:list<int> a;
std::vector<double> b;
...
for (auto t : zip(a, b)) {
   // access elements by boost::get<0>(t), boost::get<1>(t)
   // or use boost::tie(a_element, b_element)
}

当我调用其他一些方法时会出现问题,该方法需要 std::tuplestd::pair - 我必须转换),因为其余代码使用 std::tuples,或者当模板代码使用 std::get&lt;&gt;() 和/或 @ 987654333@.

我发现一些补丁添加了std::tuplezip_iterator 的支持,但这些未应用于我的版本(我使用 Boost 1.54)。

我错过了什么吗?我有哪些选项可以强制zip_iterator 返回std::tuple 或使std::getstd::tie 等可用于提升类型?

【问题讨论】:

标签: c++ c++11 boost stl tuples


【解决方案1】:

你试过了吗

#include <boost/iterator/zip_iterator.hpp>
#include <boost/range.hpp>
#include <tuple>

template <typename... TContainer> auto zip(TContainer&... containers) ->
boost::iterator_range<boost::zip_iterator<decltype(std::make_tuple(std::begin(containers)...))>> {
                                                   ^^^
    auto zip_begin = boost::make_zip_iterator(std::make_tuple(std::begin(containers)...));
                                              ^^^
    auto zip_end = boost::make_zip_iterator(std::make_tuple(std::end(containers)...));
                                            ^^^
    return boost::make_iterator_range(zip_begin, zip_end);
 }

【讨论】:

  • 是的,我有。但似乎 Boost 缺少 std::tuple 的一些类型特征。这些是由我提到的那些补丁添加的,但我在我的 Boost 版本中没有看到它们。也许我需要包含一些其他标头(例如 Boost.Fusion 中的 std::tuple 适配器)。
【解决方案2】:

在 boost >= 1.55 中使用boost::combine

for (auto a_tuple: boost::combine(va, vb)) {...}

BOOST_FOREACH(boost::tie(elem_a, elem_b), boost::combine(va, vb)) {...}

【讨论】:

  • 这取代了我对zip 函数的实现——很高兴知道。但正如我提到的,它与std::tiestd::tuple 有完全相同的问题。它返回不能取消引用到std::tuple 的 zip 迭代器的范围。也许我错过了什么......
  • 是的,但这不是我的问题 - 我询问了 STL 工具的使用,因为其余代码使用 stl:tuplestd:tie 等。
  • 是的,我也有同样的问题,但我认为带有 boost::tie 的 boost_foreach 足够干净。如果std::tuple 是不可避免的,你可以用elem_a, elem_b 再次std::make_tuple 而不是std::tuple->std::tie。所以我认为坚持std::tieboost::tuple是没有意义的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-09
  • 2017-04-16
  • 1970-01-01
  • 1970-01-01
  • 2013-11-16
  • 2017-07-31
相关资源
最近更新 更多