如何在std :: set中存储指向对象的指针(或引用)

问题描述 投票:5回答:3

[C ++ 11 STL中是否有适当的方法将对象指针存储在std::set中,并通过对象的operator <方法对其进行正确排序?

当然,有可能编写我自己的Compare类型并将其作为第二个模板参数传递给set,但我想STL将提供一种更为方便的方法。

有些搜索显示std::reference_wrapper,我认为应允许这样的代码:

#include <functional>
#include <set>

struct T {
    int val;
    bool operator <(T& other) {
        return (this->val < other.val);
    }
};

int main() {
    std::set<std::reference_wrapper<T>> s;
    T a{5};
    s.insert(a);
}

但是实际上,这会导致编译器错误:

clang++ -std=c++11 -Wall -Wextra -pedantic test.cpp -o test
In file included from test.cpp:1:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/functional:49:
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/bits/stl_function.h:235:20: error: invalid operands to binary expression ('const std::reference_wrapper<T>'
      and 'const std::reference_wrapper<T>')
      { return __x < __y; }
               ~~~ ^ ~~~

(gcc错误与之类似,但时间更长)

c++ stl
3个回答
5
投票

您需要使小于运算符成为非成员,并为其提供const参考参数:

struct T {
    int val;
};

bool operator <(const T& lhs, const T& rhs) {
    return (lhs.val < rhs.val);
}

这允许在std::reference_wrapper<T>运算符的LHS和RHS上从T<进行隐式转换,而成员版本仅允许在RHS上进行隐式转换。二进制运算符的LHS和RHS之间的对称性是将其实现为非成员的经典论据之一。


2
投票

无法对调用方法的对象进行隐式转换,因此您需要将比较实现为自由函数,以使用从reference_wrapper 到T的转换。


0
投票

正确的方法是为我们的MyStruct创建专门的std::less。>>

namespace std
{
    template<> struct  less<MyStruct>
    {
        bool operator() (const MyStruct& lhs, const MyStruct& rhs) const
        {
            return lhs.a < rhs.a;
        }
    };

}

记住std::set默认使用std::less比较两个元素。

在标题<set>中定义

template<

    class Key,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<Key>
> class set;

https://en.cppreference.com/w/cpp/container/set

© www.soinside.com 2019 - 2024. All rights reserved.