4

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;
}
4

3 に答える 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

于 2012-05-27T20:29:25.857 に答える
2

関数のパラメーターはconstでなければならないという要件が標準にあるとは思わないので、実装がそれを拒否するのは誤りだと思います。ただし、関数が引数を変更しないという要件があります。

標準から-25.4/2

Compareは関数オブジェクト型(20.8)です。Compare型のオブジェクトに適用される関数呼び出し操作の戻り値は、コンテキストでbool(4)に変換されると、呼び出しの最初の引数が2番目の引数よりも小さい場合はtrueになり、それ以外の場合はfalseになります。Compare compは、順序関係を想定したアルゴリズム全体で使用されます。compは、逆参照されたイテレータを介して非定数関数を適用しないと想定されています。

そしてstd::sort25.4.1.1からの署名

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

したがって、関数は引数を変更することを許可されていないため、実際には引数をconstとして取り込む必要がありますが、標準ではそれは必要ありません。したがって、実装にエラーがある可能性がありますが、引数を変更して関数が標準に違反しているか、定数が正しくないという事実に注意を喚起することができるため、これは許されるエラーだと思います。

于 2012-05-27T20:44:57.720 に答える
0

2つのパラメーターは同じままなので、constにする必要があります。

于 2012-05-27T20:18:23.417 に答える