c++ - STL SET 中项目的顺序因程序的不同运行而不同

标签 c++ stl set

我正在使用 STL set 容器类来存储指向对象的指针。在从 STL 集合中读取时,对于程序的不同运行,对象的顺序会因为内存(地址)到对象的动态分配而发生变化。

假设对象是 A、B、C,它们在第一次运行时的地址是 10、16、12。因此,当我将这些对象插入 set 并检索它们时,我将得到 A C B (b'caz 10<12<16) 的输出。现在,如果在下一次运行中分配的地址是 14、10、8,我将得到 C B A (8<10<14) 的输出。

有什么方法可以按特定顺序获得输出?

重载比较器(自定义比较器)可以解决问题,但那样的话我必须将它作为模板参数传递,这导致在很多地方修改代码。有没有办法避免修改我的代码,仍然能够编写客户比较器?

最佳答案

您应该传递一个按指向值排序的比较对象,而不是按指针的值排序:

struct deref_compare {
    template <typename T>
    bool operator()(T const* o0, T const* o1) const {
        return *o0 < *o1;
    }
};

std::set<int*, deref_compare> s;
// use s as before

如果您无法更改 std::set<int*> 的声明你可以技术上专攻std::less<int*>做一些不同的事情,但除非你专门涉及用户定义的类型,否则这是不允许的:

namespace std
{
    template <>
    class less<int*> {
    public:
        bool operator()(int const* o0, int const* o1) const {
            return *o0 < *o1;
        }
    };
}

请注意,在不涉及用户定义类型的情况下特化任何标准类模板会导致未定义的行为:我建议不要特化 std::less<int*> .问题在于它会影响其他代码,例如标准 C++ 库中的代码。 C++ 标准的相关部分是 17.6.4.2.1 [namespace.std] 第 1 段:

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.

关于c++ - STL SET 中项目的顺序因程序的不同运行而不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23870522/

相关文章:

c++ - 编译器如何根据优先级和关联性来解释这个表达式?

c++ - 为什么我们在 C++ 中使用 printf() 函数?

c++ - 包括 std::forward 会产生错误,但它的遗漏会编译。为什么?

c++ - 检查 vector<vector<queue<msg>>> 中的 vector 'space' 是否为空

python - 如何将列表列表转换为 python 中的集合,以便我可以与其他集合进行比较?

python - 使用 issubset 比较两个 pandas 数据框列之间的设置值

c++ - 使用 cmath 的 fmod (C++) 时的不一致

c++ - 什么是非空 STL 删除的安全等价物?

c++ - 无法将迭代器的 std::set 中的元素插入到 std::list

c++ - 为什么结构中的指针在 Visual C++ 中会出现错误,而 GCC 却不会?