簡體   English   中英

為什么STL的std :: sort無法與不可變的類一起使用?

[英]Why does STL's std::sort not work with immutable classes?

當類屬性可變時,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;
    });
}

誰能告訴我為什么?

非常感謝。

C ++的std::sort要求std::sort的迭代器實現ValueSwappable

如果T類型為ValueSwappable

  1. T型滿足迭代器要求
  2. 對於T類型的任何可解除引用的對象x(即,除最終迭代器之外的任何值),* x都滿足Swappable要求。

為了可交換,您基本上需要這樣做:

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

此外, std::sort要求以下表達式有效( MoveConstructibleMoveAssignable

定義:

  • t是類型T的可修改左值。
  • rv是類型T的右值表達式。

要求:

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

您的編譯器似乎壞了...

您提供的代碼確實符合這些要求。 因此,我不確定您的編譯器為何拒絕此代碼。 由於operator=重載,您的PersonImmutable確實實現了std::swap的要求。

但是,您的不可變對象不應該滿足此要求(因為它是不可變的)...

話雖如此,您的operator=重載將導致編譯器崩潰,因為您要通過引用返回堆棧變量。

operator=重載幾乎應該總是通過引用返回*this 這需要變異對象。 因此,在一個不變的對象中並沒有多大意義。

您真的需要對這些對象進行排序嗎?

如果必須對它們進行排序,則有一些選項。

  1. 您可以對指針向量進行排序。
  2. 您可以對不可變對象的std :: list進行排序。
  3. 還有其他選擇。

此代碼的最小(ish)測試用例...

有效的編譯器應接受以下代碼為有效代碼。 聽起來好像不是。

#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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM