【问题标题】:boost::combine, range-based for and structured bindingsboost::combine,基于范围的 for 和结构化绑定
【发布时间】:2019-04-09 05:34:57
【问题描述】:

有没有办法让boost::combine 与结构化绑定和基于范围的 for 一起工作(这样结构绑定中的标识符实际上指向容器的元素,而不是 boost::combine 在底层使用的任何嵌套元组)?以下(live example)编译失败:

#include <boost/range/combine.hpp>
#include <iostream>

int main()
{
    std::vector<int> a{1,2,3};
    std::vector<int> b{2,3,4};

    for (auto [f, s] : boost::combine(a, b))
    {
        std::cout << f << ' ' << s << std::endl   
    }
}

【问题讨论】:

    标签: c++ for-loop boost c++17


    【解决方案1】:

    真正的答案是使用boost::tie 或获取range-v3 zip(),它实际上产生std::tuple


    仅出于教育目的的答案只是为boost::tuples::cons 调整结构化绑定机制。该类型已经有一个 get() 与 ADL 一起工作并且做正确的事情,所以我们需要做的就是提供 tuple_sizetuple_element (这最终很容易做到,因为这些确切的特征已经存在于 Boost ):

    namespace std {
        template <typename T, typename U>
        struct tuple_size<boost::tuples::cons<T, U>>
            : boost::tuples::length<boost::tuples::cons<T, U>>
        { };
    
        template <size_t I, typename T, typename U>
        struct tuple_element<I, boost::tuples::cons<T, U>>
            : boost::tuples::element<I, boost::tuples::cons<T, U>>
        { };
    }
    

    但实际上不要在实际代码中这样做,因为实际上只有类型作者应该选择加入这种事情。

    这将使结构化绑定正常工作。

    【讨论】:

    • 是的,非常感谢,这正是我想要的!
    • 奇怪,为什么这不是标准的一部分?
    • @h22 因为boost 不是std 的一部分
    • 你的意思是,没有办法绕过 std:: 命名空间添加这个?我正在考虑将其作为我项目的一部分。但是我心里仍然有一些 FUD,所以我决定先问一个单独的问题。到目前为止,我见过的其他迭代多个向量的方法比删除更复杂。
    【解决方案2】:

    您可以使用boost::tie 来完成此操作。

    #include <boost/range/combine.hpp>
    #include <iostream>
    
    int main()
    {
        std::vector<int> a{1,2,3};
        std::vector<int> b{2,3,4};
        int f, s;
        for (auto var : boost::combine(a, b))        
        {
            boost::tie(f, s) = var;
            std::cout << f << ' ' << s << std::endl;   
        }
    }
    

    Demo.

    【讨论】:

    • 我想使用结构化绑定来避免预定义fs
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    • 1970-01-01
    • 2013-05-13
    • 1970-01-01
    • 2016-10-31
    • 2012-02-18
    相关资源
    最近更新 更多