Probably a dupe, but I can't find it.
After two days of nunchucking my keyboard, I have discovered that overloading the equals operator (operator=
) apparently breaks std::sort
. Maybe I'm overloading operator=
incorrectly? This is my MCVE:
#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
#include <cstdint>
#include <vector>
struct Person
{
std::string name;
uint32_t age;
bool operator< (const Person& p)
{
return this->age < p.age;
}
Person operator= (const Person& p)
{
Person newP;
newP.name = p.name;
newP.age = p.age;
return newP;
}
static bool SortPeople(const Person& p1, const Person& p2)
{
return p1.age < p2.age;
}
};
void PrintPeople(const std::vector<Person>& people)
{
std::cout << "============ people begin" << std::endl;
for (const auto& pIt : people)
{
std::cout << "name: " << pIt.name << ", age: " << pIt.age << std::endl;
}
std::cout << "============ people end" << std::endl;
}
int main()
{
std::vector<Person> people = { { "james", 12 },
{ "jada", 4 },
{ "max", 44 },
{ "bart", 7 }
};
PrintPeople(people);
std::sort(people.begin(), people.end());
PrintPeople(people);
return 0;
}
If I run this code as is, each person is not sorted based on age. PrintPeople
prints out in the same order that I initialized people
in. However, if I comment out the entire Person operator=
function, then people
does get printed out in ascending order based on age. I see this same behavior whether I call std::sort(people.begin(), people.end());
or std::sort(people.begin(), people.end(), Person::SortPeople);
, and I see this same behavior whether I use g++
version 7.2.1 or clang++
version 4.0.1. I'm running Fedora 27.
Anyone have any idea why overloading operator=
breaks std::sort
?
I'm compiling with flags -Wall -Wextra -Wconversion -std=c++11
,, there are no warnings.
Yes you're overloading operator=
wrongly. It's supposed to modify on *this
, but you're modifying on a local object newP
.
Change it to
Person& operator= (const Person& p)
{
name = p.name;
age = p.age;
return *this;
}
std::sort
sorts elements by moving them, which uses the overloaded operator=
for Person
. That's why the wrong implementation breaks std::sort
here.
BTW: When you remove the implementation, the auto-generated assignment operator does the right thing for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With