I have a class:
class Monster : public Player
{
public:
// Copy constructor - used for populating monster list in Game class
Monster(int newType)
{
type = newType;
canmove = true;
notforward = false;
}
int type;
bool operator==(const Monster& m) const {return type == m.type;}
bool operator!=(const Monster& m) const {return type != m.type;}
bool operator< (const Monster& m) const {return type < m.type;}
bool operator<=(const Monster& m) const {return type <= m.type;}
bool operator> (const Monster& m) const {return type > m.type;}
bool operator>=(const Monster& m) const {return type >= m.type;}
};
Some variables (like canmove and notforward) are inherited. Next, in a different class, I create a map of monsters:
map<pair<int, int>, Monster> monsters; // Pair used for x and y coordinate
monsters.insert(make_pair(10, 10), Monster(10));
// Error - No instance of overloaded function
How can I get the Monster instances into the monsters map? I added all the operator overloads just so I could insert, but it doesn't work!
Simple way is
monsters[make_pair(10, 10)] = Monster(10);
another way is
monsters.insert(make_pair(make_pair(10, 10), Monster(10)));
yet another is
monsters.insert(map<pair<int, int>, Monster>::value_type(make_pair(10, 10), Monster(10)));
Operator overloads are unnecessary, you do need to overload operator< for the key of a map but not for the value. I think maybe you got confused because two calls to make_pair are necessary in the second case.
Related
I have this struct
struct C {
int ID;
int age;
C(int ID, int age) : ID{ID}, age{age} {}
};
I use a comparator function for a multiset
bool fncomp (const C& lhs, const C& rhs) {
return lhs.age < rhs.age;
}
multiset<C, decltype(fncomp)*> ms{fncomp};
ms.emplace(1, 15);
...
// this works fine
ms.count(C(1, 15));
However if I use a class comparator, this is no longer working.
struct classcomp {
bool operator() (const C& lhs, const C& rhs) {
return lhs.age < rhs.age;
}
};
multiset<C, classcomp> ms;
ms.emplace(1, 15);
...
// error
// ms.count(C(1, 15));
Anything makes the two different?
Elaborating on my comment above:
multiset::count is a const member function, which means that it operates on a const multiset. This includes the member variables of the multiset. The comparator is a member variable of the multiset.
Since your classcomp::operator() is not marked const, it can't be called on a const object, and so it fails to compile.
This works for the function pointer example, because it's the pointer that is const in that case.
bool operator() (const C& lhs, const C& rhs) const {
return lhs.age < rhs.age;
}
This would fix things to compile in this link you provided, courtesy of #Marshall -> https://stackoverflow.com/a/71384594/10630957
I would like to overload possibly the string operator of my class so that I can count the number of element inserted into a std::multiset based on the key.
I would like to get the total object of type "a" given the following class:
class Item
{
public:
Item();
Item(std::string type, float price);
friend bool operator <(const Item & lhs, const Item & rhs);
friend bool operator == (const Item & lhs, const Item & rhs);
virtual ~Item();
private:
std::string type_;
float price_;
};
bool operator<(const Item & lhs, const Item & rhs)
{
return (lhs.price_ < rhs.price_);
}
bool operator == (const Item & lhs, const Item & rhs)
{
return (lhs.type_ == rhs.type_);
}
int main(){
Item a("a", 99999);
Item b("b", 2);
Item c("c", 5);
Item d("d", 5);
Item e("e", 555);
Item f("f", 568);
Item g("a", 99999);
std::multiset <Item> items_;
items_.insert(a);
items_.insert(b);
items_.insert(c);
items_.insert(d);
items_.insert(g);
items_.insert(a);
auto tota = items_.count("a");
return 0;
}
And I would expect tota to return 2 in this case.
However I am not sure to know how to proceed.
Instead of
auto tota = items_.count("a");
use
auto tota = items_.count(Item("a", 0));
The price can be anything since you don't use it in the operator< function.
I misspoke about the operator< function. It IS using price. If you want to be able to lookup by just the type, you need to change it to:
bool operator<(const Item & lhs, const Item & rhs)
{
return (lhs.type_ < rhs.type_);
}
If you want to be able to search for Items using just a string, you might want to use a std::multimap<std::string, Item> instead of std::multiset<Item>.
I try to create a custom class used with std::set. I know I need to provide a custom comparator for it so I overloaded the operator<. But when I try to copy the set with the code set<Edge> a; set<Edge> b = a;,
I get the following error:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/__functional_base:63:21: Invalid operands to binary expression ('const Edge' and 'const Edge')
class Edge {
public:
Edge(int V, int W, double Weight):v(V),w(W),weight(Weight){}
int other(int vertex){ return v ? w : vertex == w;}
int v,w;
double weight;
friend std::ostream& operator<<(std::ostream& out, const Edge& e)
{
out<<e.v<<' '<<e.w<<' '<<"weight:"<<e.weight<<'\n';
return out;
}
bool operator<(const Edge& other)
{
return weight < other.weight;
}
};
Make
bool operator<(const Edge& other) const
as the comparison operator must be marked const. The keys in a std::set are const, so the operator< is invoked on a const instance, hence must be marked const.
I am trying to initialize a priority_queue , Here is the code
class stdnt{
public:
int indx;
int c;
int lvl;
bool operator<(const stdnt &x)
{
return this->c > x.c;
}
};
priority_queue<stdnt> pq;
But its giving me error that passing const & discards qualifiers. How else am I supposed to do this?
You need to make the operator const so that it can be called on const instances or via const references or pointers to const:
bool operator<(const stdnt &x) const
^^^^^
Alternatively, make it a non-member:
bool operator<(const stdnt &lhs, const stdnt& rhs)
{
return lhs.c > rhs.c;
}
I have a class like this:
class AI
{
private:
struct Comparator
{
bool operator()(const Town* lfs, const Town* rhs)
{
return GetHeuristicCost(lfs) > GetHeuristicCost(rhs);
}
};
int GetHeuristicCost(const Town* town);
// constructor and variables
};
GetHeuristicCost returns the heuristic from the town parameter to the exit of the path.
What I am trying to do is overload the bool operator for a priority queue but it gives me the error
a nonstatic member reference must be relative to a specific object
I know why it is giving me this error but what I don't know is how to use a nonstatic function inside the Comparator struct.
GetHeuristicCost must be nonstatic
I tried moving GetHeuristicCost inside the Town class to no avail
I need to overload the operator with a struct because I need to use two different bool overloadings on the () for two different circumstances but with the same parameters (two Towns). In other words I need the struct so I can't do this:
bool operator()(const Town* lfs, const Town* rhs)
{
return GetHeuristicCost(lfs) > GetHeuristicCost(rhs);
}
Basically I plan on having two structs like this:
struct Comparator1
{
bool operator()(const Town* lfs, const Town* rhs)
{
return GetHeuristicCost(lfs) > GetHeuristicCost(rhs);
}
};
struct Comparator2
{
bool operator()(const Town* lfs, const Town* rhs)
{
return GetHeuristicCost(lfs) + GetTotalCost (lfs, rhs) > GetHeuristicCost(rhs) + GetTotalCost (lfs, rhs);
}
};
You need to construct instances of the Comparator nested class with a pointer/reference to their "outer" class instance.
class AI
{
private:
struct Comparator
{
const AI &outer;
Comparator(const AI &o):outer(o){}
bool operator()(const Town* lfs, const Town* rhs)const
{
return outer.GetHeuristicCost(lfs) > outer.GetHeuristicCost(rhs);
}
};
int GetHeuristicCost(const Town* town)const;
};
// how to use in code:
AI::Comparator comp(*this);
priority_queue<Town*, vector<Town*>, AI::Comparator> priorityQueue(comp);