【问题标题】:Overloaded template operator calling separate class operator重载模板运算符调用单独的类运算符
【发布时间】:2019-03-03 08:02:55
【问题描述】:

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

毫无疑问,我已经实现了不正确的运算符重载,因此不胜感激。

例如

#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: 在 'bool operator::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) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator >>; _Distance = int; _Tp = 动物; _比较= 标准::少]' 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: error: no matching function for call to 'Animal::operator

【问题讨论】:

  • 错误信息中写着把代码改成这样:bool Animal::operator&lt; ( const Animal&amp; b) const如果参数不是const引用类型(它是Animal&amp;),你不能用const参数调用这个操作符.

标签: c++


【解决方案1】:

你的比较

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&lt;。特别是如果你想以不同的方式对对象进行排序,我建议不要使用它,而是将 lambda 传递给priority_queue。例如,请参阅 here

【讨论】:

  • 谢谢!我在每个位置一次添加一个 const,但不是一起添加。我有点困惑为什么我们需要这样做,所以我得再用谷歌搜索一下
  • @Sarah 根据经验,您可以将每个方法声明为const,并且仅当它需要修改成员时,您才删除const。另请注意,添加const 是不够的......它可能会编译,但如果您不将比较修复为真正进行比较,则会遇到麻烦。有关详细信息,请参阅其他答案
  • @Sarah 它实际上是模板运算符 < 和 const 双方。但是,给const 的建议是尽可能地符合条件是好的
【解决方案2】:

&lt; 的两个重载都有问题

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

Animal 也应该是 const。您还需要比较这两个参数,否则期望&lt; 提供排序的事物(例如您的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 &lt; b 可以致电 会员或免费的operator &lt;。只需删除此模板即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-17
    • 1970-01-01
    • 2021-10-19
    • 2013-02-05
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    相关资源
    最近更新 更多