gpt4 book ai didi

c++ - 为什么 STL 的 std::sort 不适用于不可变类?

转载 作者:行者123 更新时间:2023-11-30 01:18:12 25 4
gpt4 key购买 nike

Std::sort 在类属性可变时有效。例如,以下代码有效,并且 vector 按预期按升序排序。

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;
});
}

谁能告诉我为什么?

非常感谢。

最佳答案

C++ 的 std::sort 要求被排序的迭代器实现 ValueSwappable .

Type T is ValueSwappable if

  1. Type T satisfies the Iterator requirements
  2. For any dereferencable object x of type T (that is, any value other than the end iterator), *x satisfies the Swappable requirements.

要实现可交换,您基本上需要这样才能工作:

using std::swap;
swap(*x, *y);

此外,std::sort 要求以下表达式有效(MoveConstructible MoveAssignable :

Definitions:

  • t is a modifiable lvalue of type T.
  • rv is an rvalue expression of type T.

Requirements:

  1. t = rv;
  2. T u = rv;
  3. T(rv);

您的编译器似乎已损坏...

您提供的代码确实满足这些要求。所以我不确定为什么你的编译器拒绝这段代码。由于 operator= 重载,您的 PersonImmutable 确实实现了 std::swap 的要求。

你的不可变对象(immutable对象)不应该满足这个要求(因为它是不可变的)......

也就是说,您的 operator= 重载将导致编译器崩溃,因为您通过引用返回堆栈变量。

operator= 重载几乎总是通过引用返回*this。这需要改变对象。所以它在不可变对象(immutable对象)中没有多大意义。

你真的需要对这些对象进行排序吗?

如果您必须对它们进行排序,有一些选项。

  1. 您可以对指针 vector 进行排序。
  2. 您可以对不可变对象(immutable对象)的 std::list 进行排序。
  3. 还有其他选择..

此代码的最小(大概)测试用例...

一个有效的编译器应该接受以下代码是有效的。听起来你的没有。

#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);
}

关于c++ - 为什么 STL 的 std::sort 不适用于不可变类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22940961/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com