重载的模板运算符调用单独的类运算符

时间:2018-09-27 11:54:31

标签: c++

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

我绝对毫无疑问地实现了错误的操作符重载,因此我们将不胜感激。

例如

#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:在'布尔运算符<(const T&,const T&)的实例中   [T =动物]':   c:\ mingw-4.7.1 \ bin ../ lib / gcc / mingw32 / 4.7.1 / include / c ++ / bits / stl_function.h:237:22:   需要来自'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:从'void std :: __ adjust_heap(_RandomAccessIterator,   _Distance,_Distance,_Tp,_Compare)[和_RandomAccessIterator = __gnu_cxx :: __ normal_iterator>>; _Distance = int; _Tp =动物; _比较=   std :: less]'   c:\ mingw-4.7.1 \ bin ../ lib / gcc / mingw32 / 4.7.1 / include / c ++ / bits / stl_heap.h:442:4:从'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:要求来自“ 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:需要'Collection :: Collection(std :: string,std :: string)[with T = Animal;   std :: string = std :: basic_string]'task.cpp:79:43:必填   从这里task.cpp:66:30:错误:没有匹配的函数可以调用   'Animal :: operator <(const Animal&)const'task.cpp:66:30:注意:   候选人是:task.cpp:36:6:注意:bool Animal :: operator <(Animal&)   const task.cpp:36:6:注意:参数1的未知转换来自   从'const Animal'到'Animal&'task.cpp:在函数'bool中   运算符<(const T&,const T&)[with T = Animal]':

2 个答案:

答案 0 :(得分:3)

您的比较

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

不能进行比较,并且应该使用const参数。您应该有类似

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

此外,您不需要为优先级队列使用成员operator<。特别是如果您想以不同的方式对对象进行排序,我建议不要使用它,而是将lambda传递给priority_queue。例如,请参见here

答案 1 :(得分:0)

<的重载都是有问题的

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

Animal也应为const。您还需要比较这两个参数,否则,期望priority_queue提供排序的事物(例如您的<)将具有不确定的行为。

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

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

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

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

此模板匹配所有类型,并且完全多余a < b可以呼叫 成员或免费的operator <。只需删除此模板即可。