#include <iostream>
#include <vector>
#include <algorithm>
class A
{
private:
int val;
public:
//ctr
A(int v) : val(v){}
// overloaded operator<
booloperator<(A* p) const { return val < p->val; }
// getter
int getVal() { return val; }
};
int main()
{
constint sz = 5;
std::vector<A*> v;
for (int i = 0; i < sz ; i++)
{
int val;
std::cin >> val;
A* p = new A(val);
v.push_back( p );
}
std::sort(v.begin(), v.end() ); // sort vector by 'val'
//print
for (int i = 0; i < v.size(); i++)
{
std::cout << "Value: " << v[i]->getVal() << std::endl;
}
// delete memory associated with each pointer
for(int i = 0; i < v.size(); i++) delete v[i];
return 0;
}
Don't ask why im creating a vector of pointers rather than straight up objects, this is just for the sake of my question.
The code above does not actually sort my vector by val. It doesn't sort it at all. The overloaded operator< does not work for a vector of pointers to objects, apparently. But as soon as I change it to a vector of objects (and modify my operator< function little), the vector gets sorted perfectly.
So why is this the case? Why does the operator< overload get used for comparing two objects, but not for two pointers to objects? I suppose my confusion arises from the fact that my operator< function itself is not comparing pointers, but ints. So whats the problem with that? Not to mention that fact that the pointers to objects being compared (or rather, the ints associated with them), are all within one container. I would expect the outcome to be the same as in the case of vector of objects.
Your overloaded < operator isn't comparing two objects of type A. Nor is it comparing two pointers to objects of type A. It's a strange mix of the two.
I suggest you declare a friend function to compare two objects by pointer.
something like this:
I know I can use a comparison function or even a functor. Im not asking about that.
Im asking why the operator< is not working with this?
Your overloaded < operator isn't comparing two objects of type A. Nor is it comparing two pointers to objects of type A. It's a strange mix of the two.
Because the operator signature compares an A with an A*.
Im not sure im understanding. Doesn't operator< take this pointer as an implicit argument? Thus both arguments are pointers to objects, and im simply comparing the int val associated with both.
If you guys can elaborate more on what exactly is wrong here, I think I can understand.
Doesn't operator< take this pointer as an implicit argument? Thus both arguments are pointers to objects, and im simply comparing the int val associated with both.
To compile the expression "a < b", the compiler looks at the type of a.
If the types of a and b are not class/struct/union/enum, it always the built-in operator< (note that means that there is no way to write an operator< that compares pointers!)
If the type of a is class/struct/union/enum, the compiler looks for every operator<(A, T) and A::operator<(T) it can find, and among those selects the ones where the type of b can be converted to T, and then among those, selects the one with the simplest conversion. (technically, the left parameter of the non-member overload can also be something to which A is convertible, but at least one parameter must be class/enum)
As mentioned, your A::operator<(A*) will be called for an expression "a < b", where a has type A and b has type pointer-to-A.
Right here. This is where im getting confused. There is an implicit this POINTER (i.e. A*) on the left hand side, and an explicit A* is being passed for the right hand side (as the vector is filled with elements of type A*). Im sorry if im being stubborn or repetitive, but im genuinely trying to understand this. Why aren't both parameters of type A*?
Isn't this: booloperator<(A* p) const { return val < p->val; }
the same as this: booloperator<(A* this, A* p) const { returnthis->val < p->val; } with the underlined portion being "invisible"?
to compile the expression a < b, in this case (with no non-member operator overloads), the compiler will attempt to call a.operator<(b). Not a->operator<(b): "a" is not permitted to be a pointer. (that is, if "a" is a pointer, it will be calling operator<(T*,T*), the built-in comparison of pointers to elements of the same array)