【问题标题】:std::set_intersection of struct objects结构对象的 std::set_intersection
【发布时间】:2018-03-08 14:58:18
【问题描述】:

我正在尝试使用std::set_intersection 获取存储类型为dist 的结构对象的两个集合的交集。我希望将结果存储在另一个set<dist>

但是,编译器给出以下错误:

In file included from /usr/include/c++/5/algorithm:62:0,
             from /usr/include/x86_64-linux-gnu/c++/5/bits/stdc++.h:64,
             from /home/kirill/CLionProjects/contest/main.cpp:1:
/usr/include/c++/5/bits/stl_algo.h: In instantiation of ‘_OutputIterator std::__set_intersection(_InputIterator1, _InputIterator1, _InputIterator2, _InputIterator2, _OutputIterator, _Compare) [with _InputIterator1 = std::_Rb_tree_const_iterator<dist>; _InputIterator2 = std::_Rb_tree_const_iterator<dist>; _OutputIterator = std::_Rb_tree_const_iterator<dist>; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’:
/usr/include/c++/5/bits/stl_algo.h:5122:48:   required from ‘_OIter std::set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter) [with _IIter1 = std::_Rb_tree_const_iterator<dist>; _IIter2 = std::_Rb_tree_const_iterator<dist>; _OIter = std::_Rb_tree_const_iterator<dist>]’
/home/kirill/CLionProjects/contest/main.cpp:65:73:   required from here
/usr/include/c++/5/bits/stl_algo.h:5076:16: error: passing ‘const dist’ as ‘this’ argument discards qualifiers [-fpermissive]
      *__result = *__first1;
            ^
/home/kirill/CLionProjects/contest/main.cpp:26:8: note:   in call to ‘dist& dist::operator=(const dist&)’
 struct dist {
    ^
CMakeFiles/contest.dir/build.make:62: recipe for target 'CMakeFiles/contest.dir/main.cpp.o' failed
make[3]: *** [CMakeFiles/contest.dir/main.cpp.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/contest.dir/all' failed
make[2]: *** [CMakeFiles/contest.dir/all] Error 2
CMakeFiles/Makefile2:79: recipe for target 'CMakeFiles/contest.dir/rule' failed
make[1]: *** [CMakeFiles/contest.dir/rule] Error 2
Makefile:118: recipe for target 'contest' failed
make: *** [contest] Error 2

这是一个结构体定义:

struct dist {
    int x_dist;
    int y_dist;

    bool operator<(dist const & b) const {
        return tie(x_dist, y_dist) < tie(b.x_dist, b.y_dist);
    }
};

这里我调用了set_intersection 方法:

#define all(c) (c).begin(), (c).end()
void intersection_taxi_fan() {
    intersection.clear();
    set_intersection(all(taxi_dist), all(fan_dist), intersection.begin());
}

【问题讨论】:

    标签: c++ stl set containers constants


    【解决方案1】:

    您不能将intersection.begin() 作为set_intersection 的参数传递,因为它是常量值的迭代器

    *注意:set 中的所有迭代器都指向 const 元素。 [来自http://www.cplusplus.com/reference/set/set/]

    set_intersection修改了这个迭代器指向的值(在set_intersection算法的sn-p代码下面的第[1]行)。

        else if (*first2<*first1) ++first2;
    else {
      *result = *first1;   // [1] try modifying const value
      ++result; ++first1; ++first2;
    }
    

    常量对象不能被修改。

    您可以使用std::inserter 将元素插入到您的intersection 集合中

        set_intersection(all(taxi_dist), all(fan_dist), inserter(intersection, intersection.end()));
    

    【讨论】:

    • 比 const 或 non-const 更相关的是,set::begin() 在调用 set::clear() 后不会返回有效的迭代器。所以 OP 代码是错误的,即使 set::begin() 会将迭代器返回到非常量值。您的解决方案是正确的,但解释可以改进。
    猜你喜欢
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 2019-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    相关资源
    最近更新 更多