C++ 试图将 std::pair 插入 std::set

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5278613/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:48:15  来源:igfitidea点击:

trying to insert std::pair into std::set

c++stl

提问by xela

i can't understand what the error is in this code:

我无法理解此代码中的错误是什么:

#include <set>
#include <utility>
#include <iostream>

using namespace std;

class A
{
    public:
        A(unsigned int a) : _a(a) { }
        A() : _a(0) { }
        unsigned int a() const { return _a; }
    private:
        unsigned int _a;
};

class B
{
    public:
        B(unsigned int b) : _b(b) { }
        B() : _b(0) { }
        unsigned int b() const { return _b; }
    private:
        unsigned int _b;
};

void display(const Point& point)
{
    //cout << "A: " << point.first.a() << ", B: " << point.second.b() << endl;
}

typedef pair <A, B> Point;
typedef set <Point> List;

main()
{
    A a(5);
    B b(9);

    List list;
    List::iterator it;
    Point point;

    point = make_pair(a, b);

    it = list.begin();

    list.insert(point); // <--- error here

    //display(point);
}

error is this:

错误是这样的:

In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/include/g++-v4/bits/stl_algobase.h:66,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/include/g++-v4/bits/stl_tree.h:62,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/include/g++-v4/set:60,
                 from test.cpp:1:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/include/g++-v4/bits/stl_pair.h: In function ‘bool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) [with _T1 = A, _T2 = B]':
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/include/g++-v4/bits/stl_function.h:230:   instantiated from ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = std::pair<A, B>]'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/include/g++-v4/bits/stl_tree.h:1170:   instantiated from ‘std::pair<typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(const _Val&) [with _Key = std::pair<A, B>, _Val = std::pair<A, B>, _KeyOfValue = std::_Identity<std::pair<A, B> >, _Compare = std::less<std::pair<A, B> >, _Alloc = std::allocator<std::pair<A, B> >]'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/include/g++-v4/bits/stl_set.h:411:   instantiated from ‘std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const _Key&) [with _Key = std::pair<A, B>, _Compare = std::less<std::pair<A, B> >, _Alloc = std::allocator<std::pair<A, B> >]'
test.cpp:48:   instantiated from here
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/include/g++-v4/bits/stl_pair.h:154: error: no match for ‘operator<' in ‘__x->std::pair<A, B>::second < __y->std::pair<A, B>::second'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/include/g++-v4/bits/stl_pair.h:154: error: no match for ‘operator<' in ‘__y->std::pair<A, B>::first < __x->std::pair<A, B>::first'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/include/g++-v4/bits/stl_pair.h:154: error: no match for ‘operator<' in ‘__x->std::pair<A, B>::first < __y->std::pair<A, B>::first'

回答by Matteo Italia

You are trying to use std::setwith an element type that does not have ordering (std::pair), while a set needs that its elements have "a specific strict weak ordering criterion".

您正在尝试使用std::set没有排序 ( std::pair)的元素类型,而集合需要其元素具有“特定的严格弱排序标准”。



Update: actually std::pairdoesprovide an operator<(thanks @UncleBens), that is defined in terms of the operator<of its components; so the problem lies in your Aand Bnot providing a comparison operator; you should write an operator<for Aand B.

更新:实际上std::pair确实提供了一个operator<(感谢@UncleBens),它是根据operator<其组件定义的;所以问题在于您AB没有提供比较运算符;你应该写一个operator<forAB

In alternative, since an operator<in general doesn't really make sense for points, you can create a comparison functor for your Points and pass it as the second template argument for std::set.

或者,由于 anoperator<通常对点没有意义,因此您可以为Points创建一个比较函子并将其作为 的第二个模板参数传递std::set

回答by Erik

pairand setare templates, not classes. You need to do e.g:

pair并且set是模板,而不是类。你需要做例如:

typedef pair<A, B> Point;
typedef set<Point> List;

A template becomes a class when you instantiate it, e.g. std::set<int> theset;creates the classset<int>from the class templateset.

模板变成当你实例化它的一类,例如std::set<int> theset;创建set<int>类模板set

EDIT: As phooj pointed out, you need both A and B to have a comparison operator, operator<. See Matteo Italia's answer.

编辑:正如 phooj 指出的,你需要 A 和 B 都有一个比较运算符,operator<。请参阅 Matteo Italia 的回答。

回答by Uday Hiwarale

#include <set>

int main(){

    typedef pair<int, int> pairs; //creating pair as default data type 
    pairs p[5]; //array of pair objects
    for (int i =0; i<5; i++){
        p[i].first= (i+1)*10; //inserting first element of pair
        p[i].second = (i+1); //inserting first element of pair
    }
    set<pairs> s;   //set to sort pair
    set<pairs> :: iterator it; //iterator to manipulate set

    for (int i =0; i<5; i++){
        s.insert(p[i]); //inserting pair object in set
    }

    for (it = s.begin(); it!=s.end(); it++){
        pairs m = *it; // returns pair to m

    cout<<m.first<<" "<<m.second<<endl; //showing pair elements
    }
    return 0;
}

回答by yasouser

You did not specify what's the type of the elements of the setand pairare going to be.

没有指定什么的元素的类型setpair将要。

Changing the lines

改变线路

typedef pair Pointto typedef pair<A, B> Pointand typedef set Listto typedef set<Point> Listshould fix your problem.

typedef pair Pointtotypedef pair<A, B> Pointtypedef set Listtotypedef set<Point> List应该可以解决您的问题。

One pedantic comment: Naming a setas Listkind of misleads when you read the code.

一个迂腐的评论:在阅读代码时将a 命名setList一种误导。

回答by solidSnake

For any user type, that is being stored in an associative container like set/map the type definition must provide ' < ' operation on it.

对于任何存储在关联容器(如 set/map)中的用户类型,类型定义必须对其提供 ' < ' 操作。