[英]Why does STL's std::sort not work with immutable classes?
Std::sort works when class properties are mutable. 当类属性可变时,Std :: sort起作用。 For example the following code works and the vector is sorted in ascending order as expected. 例如,以下代码有效,向量按预期升序排序。
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;
});
}
But the same class when made immutable isn't compatible with std::sort. 但是,当同一类变为不可变时,它与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;
});
}
Can anyone tell me why? 谁能告诉我为什么?
Many thanks. 非常感谢。
C++'s std::sort
requires that the iterators being sorted implement ValueSwappable
. C ++的std::sort
要求std::sort
的迭代器实现ValueSwappable
。
Type T is ValueSwappable if 如果T类型为ValueSwappable
And to be swappable, you basically need this to work: 为了可交换,您基本上需要这样做:
using std::swap;
swap(*x, *y);
Additionally, std::sort
requires the following expressions to be valid ( MoveConstructible and MoveAssignable : 此外, std::sort
要求以下表达式有效( MoveConstructible和MoveAssignable :
Definitions: 定义:
t
is a modifiable lvalue of typeT
.t
是类型T
的可修改左值。rv
is an rvalue expression of typeT
.rv
是类型T
的右值表达式。Requirements: 要求:
t = rv;
T u = rv;
T(rv);
The code you have presented does meet these requirements. 您提供的代码确实符合这些要求。 So I'm not sure why your compiler is refusing this code. 因此,我不确定您的编译器为何拒绝此代码。 Your PersonImmutable
does implement the requirements of std::swap
because of the operator=
overload. 由于operator=
重载,您的PersonImmutable
确实实现了std::swap
的要求。
That being said, your operator=
overload will cause the compiler to crash, because you're returning a stack variable by reference. 话虽如此,您的operator=
重载将导致编译器崩溃,因为您要通过引用返回堆栈变量。
An operator=
overload should almost always return *this
by reference. operator=
重载几乎应该总是通过引用返回*this
。 Which requires mutating the object. 这需要变异对象。 So it doesn't make much sense in an immutable object. 因此,在一个不变的对象中并没有多大意义。
If you have to sort them, there are some options. 如果必须对它们进行排序,则有一些选项。
A valid compiler should accept the following code as valid. 有效的编译器应接受以下代码为有效代码。 It sounds like yours does not. 听起来好像不是。
#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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.