【问题标题】:C++: find in set of pointersC ++:在指针集中查找
【发布时间】:2014-11-10 18:33:57
【问题描述】:

下面的例子说明了我的问题:

#include <set>

class A {};

int main()
{
    A a;
    A * p = &a;
    const A * cp = &a;

    std::set<A*> s;
    s.insert(p);
    s.find(cp);
}

编译结束于:

a.cpp: In function ‘int main()’:
a.cpp:13:18: error: invalid conversion from ‘const A*’ to ‘std::set<A*>::key_type {aka A*}’ [-fpermissive]
         s.find(cp);
                  ^
In file included from /usr/include/c++/4.9.1/set:61:0,
                 from a.cpp:1:
/usr/include/c++/4.9.1/bits/stl_set.h:701:7: note: initializing argument 1 of ‘std::set<_Key, _Compare, _Alloc>::iterator std::set<_Key, _Compare, _Alloc>::find(const key_type&) [with _Key = A*; _Compare = std::less<A*>; _Alloc = std::allocator<A*>; std::set<_Key, _Compare, _Alloc>::iterator = std::_Rb_tree_const_iterator<A*>; std::set<_Key, _Compare, _Alloc>::key_type = A*]’
       find(const key_type& __x)

我知道为什么它不能编译,但是有没有比s.find((A*)cp) 更丑陋和残酷的解决方案? set 和 const 指针都给出了。

【问题讨论】:

  • 将集合的类型更改为set&lt;const A*&gt; 是一个选项吗?
  • but is there any solution less ugly and brutal 没有指针集。
  • const A *A * 不同!
  • @PaulMcKenzie 一组智能指针再好不过了。
  • find 中,您正在搜索const 元素,但是该集合被声明为具有非常量元素。

标签: c++ pointers stl constants


【解决方案1】:

一种选择是将 C++14 transparent operator functorsheterogeneous lookup 一起使用:

std::set<A*, std::less<>> s;
s.find(cp);

不幸的是,libstdc++ 目前不支持异构查找,但 it's marked as WIP。 (在下一版本的 Visual Studio 中可以在 clang/libc++ 和 will be available 中使用它。)如果没有它,您将几乎无法使用 const_cast'ing cp

【讨论】:

  • 嗯,你快了半分钟。我浏览了 github 草稿并使用了 blame 来查找那些文档编号..
  • @dyp 我作弊并使用了 libstdc++ 状态页面 :)
  • 好吧,我至少可以在这里粘贴我的实时示例(并从 OP 中删除我的评论)。 coliru.stacked-crooked.com/a/3ab721111ad74620(“我只证明了它可以编译,没试过”)
  • Boost 多索引容器长期存在异构查找。我希望 Boost.Container 有更多这样的功能,但当时没有。
【解决方案2】:

可悲的是,set 的查询方法没有在键类型上进行模板化(它们确实应该如此),所以lower_boundequal_range 等都无济于事。

假设变量类型不可协商,您唯一的选择是丢弃指针的常量,或者将reinterpret_cast 设置为set&lt;const A*&gt;。后者在某些方面对我来说感觉更好,但它在技术上是不安全的。

摒弃不变。使用const_cast 来做这件事,以表明这是演员唯一要做的事情。如果您愿意,可以将其和 find 包装在一个免费函数中;如果一段代码是邪恶的,最好让邪恶的东西成为它唯一做的事情。

【讨论】:

  • “可悲的是,set 的查询方法没有在键类型上进行模板化(它们确实应该如此)” 这有好有坏。我记得一个错误是由这种异构查找成员函数与同构比较函数相结合(导致每次比较转换)引起的。请参阅 T.C. 的回答。
【解决方案3】:

您可以将 find 与 const_cast 一起使用:

s.find(const_cast<A*>(cp));

【讨论】:

    猜你喜欢
    • 2012-08-29
    • 1970-01-01
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多