简体   繁体   中英

possible bug in boost transformed adaptor

Im finding a bug between debug and release builds of the following code.

    #include <vector>
    #include <iostream>
    #include <boost/bind.hpp>
    #include <boost/range/algorithm.hpp>
    #include <boost/range/adaptors.hpp>
    using namespace std;
    namespace br = boost::range;
    namespace badpt = boost::adaptors;
    std::pair<int,int> pr_swap(std::pair<int,int> pr)
    {return make_pair(pr.second,pr.first);}

    int main()
    {
      std::vector<pair<int,int> > vec;
      vec.push_back(make_pair(1,2));
      vec.push_back(make_pair(2,1));
      br::copy(vec|badpt::transformed(bind(pr_swap,_1))|badpt::map_keys,std::ostream_iterator<int>(cout," "));
    }

With, gcc-4.8.1 -O3, I get

    0 0

And without I get as expected

    2,1

Any ideas what is going wrong?

I ran into this problem recently.

The implementation of select_first (ie which is used by map_keys ) in boost/range/adaptor/map.hpp returns a reference. The output of the pr_swap function returns a value. This is undefined behavior, which typically is only exposed when compiler optimizations are enabled.

I do not know why the compiler failed to emit a return-local-addr warning.

I got around the problem in the following manner:

#include <iostream>
#include <vector>
#include "boost/range/algorithm.hpp"
#include "boost/range/adaptors.hpp"

int main()
{
    const std::vector<std::pair<int, int>> v{{1,2},{3,4},{5,6}};
    auto swap = [](const auto& p) { return std::make_pair(p.second, p.first); };
    auto getFirst = [](const auto& p) { return p.first; };
    auto rng = v | boost::adaptors::transformed(swap) | boost::adaptors::transformed(getFirst);
    boost::copy(rng, std::ostream_iterator<int>(std::cout, ", "));
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM