关于c ++:重载模板运算符调用单独的类运算符


Overloaded template operator calling separate class operator

我有一个包含其他类的优先级队列的模板类,我需要使用优先级重载器来调用单个类重载器,根据单个类的首选项进行比较(在本例中,它是年龄,在另一个类中,它可能是价格)。

毫无疑问,我已经实现了不正确的运算符重载,所以我会很感谢您的建议。

例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
#include <queue>
#include <string>

using namespace std;    

class Animal {
    public:
        Animal();
        Animal(string t, int a);
        int get_age()const;
        bool operator< ( Animal& b) const;
        void display()const;
    private:
        string type;
        double age;
};

void Animal::display() const
{
    cout <<"Type:" << type <<"    Age:" << age;
}
int Animal::get_age() const
{
    return age;
}

Animal::Animal(){}

Animal::Animal(string t, int a)
{
    type = t;
    age = a;
}

bool Animal::operator< ( Animal& b) const
{
    return b.get_age();
}

template<typename T>
class Collection {
    public:
        Collection();
        Collection(string n, string d);
        void add_item(const T& c);
    private:
        priority_queue <T> pets;
        string name; // Name of the collection
        string description; // Descriptions of the collection
};

template<typename T>
Collection<T>::Collection(){}

template<typename T>
Collection<T>::Collection(string n, string d)
{
    name = n;
    description = d;
}

template<typename T>
bool operator<(const T& one, const T& two)
{
     return one.operator<(two);
}

template<typename T>
void Collection<T>::add_item(const T& c)
{
    pets.push(c);
}

int main(){
    Animal p1("Dog", 10);
    Animal p2("Cat", 5);
    Animal p3("Turtle", 24);
    Collection<Animal> P("Pets","My Pets");
    P.add_item(p1);
    P.add_item(p2);
    P.add_item(p3);
    cout << endl;

    return 0;
}

我得到这个错误,我不确定我需要做什么来修复它。我必须将类重载保持为单个变量(animal&b)。

task.cpp: In instantiation of 'bool operator<(const T&, const T&) [with T = Animal]': c:\mingw-4.7.1\bin../lib/gcc/mingw32/4.7.1/include/c++/bits/stl_function.h:237:22: required from 'bool std::less<_Tp>::operator()(const _Tp&, const _Tp&)
const [with _Tp = Animal]'
c:\mingw-4.7.1\bin../lib/gcc/mingw32/4.7.1/include/c++/bits/stl_heap.h:310:4: required from 'void std::__adjust_heap(_RandomAccessIterator,
_Distance, _Distance, _Tp, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator > >; _Distance = int; _Tp = Animal; _Compare =
std::less]'
c:\mingw-4.7.1\bin../lib/gcc/mingw32/4.7.1/include/c++/bits/stl_heap.h:442:4: required from 'void std::make_heap(_RandomAccessIterator,
_RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator > >; _Compare = std::less]'
c:\mingw-4.7.1\bin../lib/gcc/mingw32/4.7.1/include/c++/bits/stl_queue.h:393:9: required from 'std::priority_queue<_Tp, _Sequence, _Compare>::priority_queue(const _Compare&, const _Sequence&) [with _Tp = Animal; _Sequence = std::vector >; _Compare = std::less]' task.cpp:57:45: required from 'Collection::Collection(std::string, std::string) [with T = Animal;
std::string = std::basic_string]' task.cpp:79:43: required
from here task.cpp:66:30: error: no matching function for call to
'Animal::operator<(const Animal&) const' task.cpp:66:30: note: candidate is: task.cpp:36:6: note: bool Animal::operator<(Animal&) const task.cpp:36:6: note: no known conversion for argument 1 from 'const Animal' to 'Animal&' task.cpp: In function 'bool operator<(const T&, const T&) [with T = Animal]':


你的比较

1
2
3
4
bool Animal::operator< ( Animal& b) const
{
    return b.get_age();      // returns true always unless age == 0
}

不是比较,应该取一个const参数。你应该吃点像

1
2
3
4
5
bool Animal::operator< (const Animal& b) const
                       // ^----------------------- const !
{
    return get_age() < b.get_age();
}

顺便说一句,您不需要将成员operator<用于优先级队列。特别是如果你想以不同的方式对对象排序,我建议不要使用它,而是将lambda传递给priority_queue。请看这里的例子。


你的两个<过载都是有问题的。

1
bool Animal::operator< ( Animal& b) const

Animal也应该是const。您还需要比较这两个参数,否则期望<提供一个命令的东西(例如您的priority_queue)将具有未定义的行为。

您不使用任何来自Animal的非公开内容,因此我建议您将其更改为

1
2
bool operator< (const Animal & lhs, const Animal & rhs)
{ return lhs.get_age() < rhs.get_age(); }

这样做的好处是对双方都一视同仁,而不是一方含蓄。

1
2
3
4
5
template<typename T>
bool operator<(const T& one, const T& two)
{
     return one.operator<(two);
}

此模板匹配所有类型,完全多余。a < b可以调用成员或自由operator <。只需删除此模板。