我有一个用std::shared_ptr
包装的类,我想在std::priority_queue
的帮助下选择前k个对象。因此,我定义了operator <
,并希望一切都会好起来的。但这不是真的。默认情况下(带有gcc)std::priority_queue
对std::shared_ptr
使用默认比较器,它比较地址。
但是,如果我对std :: vector使用std :: sort且未指定比较器,则行为会有所不同,我的operator <
将被使用。这有点出乎意料且行为不一致。
代码示例:
struct document
{
float rank;
document(float rank):
rank(rank)
{ }
};
using doc_ptr = shared_ptr<document>;
bool operator < (const doc_ptr& x, const doc_ptr& y)
{
return x->rank < y->rank;
}
int main()
{
priority_queue<doc_ptr> pq;
for(int i = 0; i < 10; i++) {
float r = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
pq.push(make_shared<document>(r));
}
vector<doc_ptr> pq_v;
while(!pq.empty()) {
cout << pq.top()->rank << " " << uint64_t(pq.top().get()) << endl;
pq.pop();
}
return 0;
}
我得到以下输出:
0.277775 35463848
0.76823 35463800
0.335223 35463752
0.197551 35463704
0.55397 35463560
0.911647 35463512
0.783099 35463384
0.79844 35463336
0.394383 35463288
0.840188 35463208
使用clang(Apple LLVM版本9.1.0(clang-902.0.39.2)),一切正常。
std::priority_queue
中包含std::sort
和std::vector
的完整代码:https://ideone.com/awsdrO
我想这可能与名称解析有关,但我自己找不到。所以,我想知道谁在这里,为什么?
UPD :这里更简单的示例:https://ideone.com/wm1YBw
输出的最后一行在gcc和clang中有所不同,因为gcc为std::less
提供了shared_ptr
的专门化,但是clang没有。
答案 0 :(得分:0)
事实证明,gcc为std::less
提供了std::shared_ptr
的专业化,不应提供。您可以在this错误报告中找到所有其他详细信息。
如果我正确理解:C ++标准的早期草案已明确提及,则应为std::less
提供std::shared_ptr
的专业化。在工作过程中,此提及已从标准中删除,但在gcc代码本身中并未删除。
因此,如果您使用的是未修复的gcc版本,请小心。