C++ 对Vertex指针vector使用sort时出现编译错误的问题
编译报错核心成因
这个报错是比较器类型不匹配触发的,具体来自两处代码问题:
- Lambda参数类型不兼容
你定义的比较器形参为const Vertex*& one, const Vertex*& two,这里的const修饰的是指针指向的Vertex对象,最终形成的形参类型是「对指向const Vertex的指针的普通左值引用」。
但vector<Vertex*>的迭代器解引用后得到的是Vertex*&类型的左值(指向非const Vertex的指针引用),将这类值转换为const Vertex*类型时会生成一个临时的右值对象,而C++不允许将临时右值绑定到普通左值引用上,因此类型匹配失败。当sort内部尝试调用比较器传入元素值时,就会因为参数类型不匹配,触发“没有匹配的可调用对象”的编译错误。const的位置写错是这里最容易踩的坑——把const放在指针类型前面和放在指针后面,修饰的对象完全不同。 - 比较逻辑冗余无效
你写的比较表达式&*one < &*two没有实际意义:one本身就是指向Vertex的指针,*one是对指针解引用得到的Vertex对象,再取地址得到的结果和one本身完全相等,属于无意义的绕路操作。
修复方法
- 修正比较器的参数定义,匹配实际传入的元素类型
最简洁高效的写法是直接以值传递的方式接收指针参数,完全避开引用绑定的兼容问题,同时删掉冗余的解引用取地址操作:
如果习惯用引用传参降低传值开销(实际上指针大小和普通int一致,传值几乎没有额外开销),需要把const的位置调整到星号右侧,让const修饰指针本身,此时形参类型为「指向非const Vertex的常指针左值引用」,就可以正常绑定到迭代器解引用得到的void test(vector<Vertex*>& other) { sort(vertices.begin(), vertices.end(), [](Vertex* one, Vertex* two) { return one < two; }); sort(other.begin(), other.end(), [](Vertex* one, Vertex* two) { return one < two; }); }Vertex*&值上:sort(vertices.begin(), vertices.end(), [](Vertex* const& one, Vertex* const& two) { return one < two; }); - 适配实际业务需求调整比较逻辑
以上写法是按照Vertex对象在内存中的地址进行排序,如果实际使用中需要按照顶点id排序,只需要把比较逻辑换成基于Vertex成员的判断即可:sort(vertices.begin(), vertices.end(), [](Vertex* one, Vertex* two) { return one->get_id() < two->get_id(); });
内容的提问来源于stack exchange,提问作者Jacob
相关产品推荐
相关产品推荐

