当类属性可变时,Std :: sort有效。例如,以下代码有效,矢量按预期按升序排序。
class PersonMutable
{
public:
PersonMutable(int age, std::string name):
Age(age),Name(name)
{
}
int Age;
std::string Name;
};
void TestSort()
{
std::vector<PersonMutable> people;
people.push_back(PersonMutable(24,"Kerry"));
people.push_back(PersonMutable(30,"Brian"));
people.push_back(PersonMutable(3,"James"));
people.push_back(PersonMutable(28,"Paul"));
std::sort(people.begin(),people.end(),
[](const PersonMutable& a, PersonMutable & b) -> bool
{
return a.Age < b.Age;
});
}
但是,当不可变时,同一个类与std :: sort不兼容。
class PersonImmutable
{
public:
PersonImmutable(int age, std::string name):
Age(age),Name(name)
{
}
PersonImmutable& operator=(const PersonImmutable& a)
{
PersonImmutable b(a.Age,a.Name);
return b;
}
const int Age;
const std::string Name;
};
void TestSort()
{
std::vector<PersonImmutable> people;
people.push_back(PersonImmutable(24,"Kerry"));
people.push_back(PersonImmutable(30,"Brian"));
people.push_back(PersonImmutable(3,"James"));
people.push_back(PersonImmutable(28,"Paul"));
std::sort(people.begin(),people.end(),
[](const PersonImmutable& a, PersonImmutable & b) -> bool
{
return a.Age < b.Age;
});
}
谁能告诉我为什么?
非常感谢。
答案 0 :(得分:5)
C ++的std::sort
要求被排序的迭代器实现ValueSwappable
。
如果
,则类型T为ValueSwappable
- 类型T满足迭代器要求
- 对于任何类型为T的dereferencable对象x(即除了结束迭代器之外的任何值),* x满足Swappable要求。
醇>
并且可以交换,你基本上需要这个工作:
using std::swap;
swap(*x, *y);
此外,std::sort
要求以下表达式有效(MoveConstructible 和MoveAssignable:
说明:
t
是T
类型的可修改左值。rv
是T
类型的右值表达式。要求:
t = rv;
T u = rv;
- 醇>
T(rv);
您提供的代码确实符合这些要求。所以我不确定为什么你的编译器拒绝这个代码。由于PersonImmutable
超载,您的std::swap
确实实现了operator=
的要求。
话虽这么说,你的operator=
重载会导致编译器崩溃,因为你通过引用返回一个堆栈变量。
operator=
重载几乎总是通过引用返回*this
。这需要改变对象。所以它在一个不可变的对象中没有多大意义。
如果你必须对它们进行排序,有一些选择。
有效的编译器应接受以下代码作为有效代码。听起来你的不是。
#include <string>
class PersonImmutable {
public:
PersonImmutable(int age): Age(age) {}
PersonImmutable operator=(const PersonImmutable& a) {
return *this;
}
private:
const int Age;
};
int main() {
PersonImmutable a(1, "a");
PersonImmutable b(2, "b");
using std::swap;
swap(a,b);
}