为什么我不能定义没有常量的比较

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

如果我像这样定义我的

compare
函数:

bool compare(Student& a, Student& b)
{
    return a.n < b.n;
}

g++会抱怨:

g++ -Wall main.cpp -o main
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/algorithm:63:0,
                 from main.cpp:1:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/stl_algo.h: In function ‘_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Student*, std::vector<Student> >, _Tp = Student, _Compare = bool (*)(Student&, Student&)]’:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/stl_algo.h:2261:78:   instantiated from ‘_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Student*, std::vector<Student> >, _Compare = bool (*)(Student&, Student&)]’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/stl_algo.h:2302:62:   instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Student*, std::vector<Student> >, _Size = long int, _Compare = bool (*)(Student&, Student&)]’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/stl_algo.h:5250:4:   instantiated from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<Student*, std::vector<Student> >, _Compare = bool (*)(Student&, Student&)]’
main.cpp:38:51:   instantiated from here
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/stl_algo.h:2229:4: error: invalid initialization of reference of type ‘Student&’ from expression of type ‘const Student’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/stl_algo.h:2232:4: error: invalid initialization of reference of type ‘Student&’ from expression of type ‘const Student’

Compilation exited abnormally with code 1 at Mon May 28 08:05:35

但是如果我定义与

const
类型的比较,它将编译并正常工作。

这是所有代码:

class Student {
public:
    Student(string);
    string n;

};

bool compare(Student& a, Student& b)
{
    return a.n < b.n;
}

Student::Student(string name) { n = name; }

int main()
{
    Student A = Student("A");
    Student B = Student("B");

    vector<Student> students;
    students.push_back(B);
    students.push_back(A);

    sort(students.begin(), students.end(), compare);

    cout << "After sort" << endl;
    for(vector<Student>::iterator i = students.begin(); i != students.end(); ++i) {
        cout << "Student: " << i->n << endl;
    }

    return 0;
}
c++ g++
3个回答
6
投票

在此实现中,

std::sort
使用

 const _Tp& std::__median(const _Tp&, const _Tp&, const _Tp&, _Compare);

就您而言,

_Tp
是学生,
_Compare
compare

所以你基本上已经有了

const Student& std::__median(const Student&, const Student&, const Student&, 
                                                   bool (*)(Student&, Student&) )

或类似的。显然,回调不能应用于参数,因为它们被转换为

const
,所以失败。

为您的

compare
方法设置参数
const


2
投票

我不认为标准中要求函数的参数必须是 const,所以我相信您的实现是错误的,拒绝它。 但是,要求函数不能修改参数:

来自标准——25.4/2

Compare 是一个函数对象类型(20.8)。返回值 函数调用操作应用于 Compare 类型的对象,当 根据上下文转换为 bool (4),如果第一个参数则产生 true 调用的值小于第二个,否则为 false。比较比较 用于假设排序关系的算法。这是 假设 comp 不会通过以下方式应用任何非常量函数 解引用迭代器。

以及来自25.4.1.1的

std::sort
的签名

template<class RandomAccessIterator, class Compare>
void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)

因此,由于您的函数不允许修改其参数,因此它确实应该将它们作为 const 接受,但标准并不要求这样做。 因此,虽然您的实现可能有错误,但我相信这是一个可以原谅的错误,因为它设法引起人们注意这样一个事实:您的函数通过修改其参数而违反了标准,或者它不是 const 正确的。


0
投票

您应该将其设置为常量,因为它使两个参数保持不变。

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