我正在使用 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 namespacestd
unless otherwise specified. A program may add a template specialization for any standard library template to namespacestd
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/