【问题标题】:Why does std::sort() change the sorted vector?为什么 std::sort() 会更改已排序的向量?
【发布时间】:2011-12-19 01:35:41
【问题描述】:

问题来了:

在我的第一堂课中,我有一个向量、一个双精度变量,并且我重载了比较运算符。以下是相关代码:

class City
{
    double distance;
    std::vector<int> coordinates;

    bool operator<(const City& city) const
    {   
        return this->distance < city.distance;
    } 

    // same for the greater-than operator but changing "<" to ">"
};

在另一个类中,我有一个城市向量,每次满足条件时我都必须对其进行排序。为此,我定义了一个结构如下:

编辑:(引用而不是值)

struct CitySortHelper {
    bool operator() (const City &x, const City &y) const { return x < y; } 
} city_sort;

现在的问题是,当我对向量进行排序时,出现了新的 City 对象,我无法解释原因:

编辑:

// this prints all current objects in the vector
for (int i = 0; i < totalCities; i++) {
    std::cout << cities->at(i) << std::endl;
}

// after the following line I get new City objects in the 
// vector, that weren't there before the sort. The new objects
// always have distance = 0 and random values in the coordinates
std::sort(cities->begin(), cities->end(), city_sort);

// using the sort with no predicate also gives the same faulty results
std::sort(cities->begin(), cities->end());

编辑:(复制构造函数和赋值运算符)

City(const City &city)
{
    this->distance = city.distance;
    this->coordinates = city.coordinates;
}

City& operator= (const City &city)
{
    this->distance = city.distance;
    this->coordinates = city.coordinates;

    return *this;
}

奇怪的是,这只发生在我按升序对 City 对象进行排序时,即如果我将 CitySortHelper 中的比较器运算符从“”,一切正常。

任何想法为什么会发生这种情况?任何帮助表示赞赏。

【问题讨论】:

  • 你的 City 类有专门的拷贝构造函数吗?
  • 如果可以只使用std::sort(cities-&gt;begin(), cities-&gt;end())std::sort(cities-&gt;begin(), cities-&gt;end(), std::greater&lt;City&gt;),为什么还需要自定义谓词?
  • @KerrekSB 我也试过不使用谓词。在正常情况下,即使用 less-operator 的std::sort(cities-&gt;begin(), cities-&gt;end()),我仍然会得到那些新对象。而使用std::greater没有问题。
  • 我无法重现您的问题。您需要提供一个完整的、可编译的示例来演示该问题。
  • 你说你可以使用std::greater,但我没有看到任何City::operator>()。在我看过的所有 STL impls(即 gcc 就是这样)上,std::greater() 只是转发给 operator>。如果您已经定义了 City::operator>,那么发布它可能会有所帮助。

标签: c++ sorting std


【解决方案1】:

CitySortHelper 需要通过 const 引用而不是值来获取参数。要记住的另一件事是,sort 对City 使用赋值运算符;检查您的赋值运算符是否正常工作。处理好这两个问题应该可以解决问题。

【讨论】:

  • 我更改了CitySortHelper 并检查了赋值运算符和复制构造函数。问题仍然存在。它适用于降序,但不适用于升序。
  • @iska 您能否更新问题以反映您所做的更改?
  • 给你。现在我坚持按降序排序,然后反转向量:(
  • @iska 你确定totalCities 等于cities-&gt;size() 吗?我刚刚将您的代码复制到一个 CPP 文件中,它按升序排序。
  • 是的,事实上这是我在这里问之前检查的第一件事。
【解决方案2】:

将您的排序助手更改为具有

bool operator() ( const City& x , const City& y) const

还要检查 City 复制构造函数和赋值运算符是否正确

【讨论】:

  • 我更改了CitySortHelper 并检查了赋值运算符和复制构造函数。问题仍然存在。它适用于降序,但不适用于升序。
【解决方案3】:

如果你想保持秩序,你不应该使用std::sort(),你应该使用std::stable_sort()stable_sort 保证元素保持它们的相对顺序,sort 不保证。

此外,sort 似乎不是您的问题。似乎有 City 对象被推入某个向量中,而您没有注意到它们,因为您正在检查变量的大小而不是向量的迭代器。尝试像这样打印并告诉我们结果如何:

for (std::vector <City> ::iterator it = cities->begin(); it != cities->end(); ++it) {
    std::cout << *it << std::endl;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-18
    • 2021-01-13
    • 2021-01-21
    • 1970-01-01
    • 2013-07-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    相关资源
    最近更新 更多