【问题标题】:C++ std::unordered_set find/count/contains const key referenceC++ std::unordered_set 查找/计数/包含常量键引用
【发布时间】:2020-07-26 07:24:45
【问题描述】:

我有一个std::unordered_set<int *>(在我的真实代码中,我使用指向类的指针,但int * 也适用于这个示例)并且想要检查给定的指针是否存储在该集合中。由于函数contains 仅适用于C++20,所以我使用函数size_type count( const Key& key ) const

如果我现在正在搜索 const 指针而不是指针,则编译将失败并显示消息 error: invalid conversion from ‘const int*’ to ‘std::unordered_set<int*>::key_type {aka int*}’ [-fpermissive]

示例代码:

#include <unordered_set>

int main() {
    std::unordered_set<int *> set {};

    int foo = 42;
    set.insert(&foo);

    int *pointer = &foo;
    set.count(pointer); // works fine

    const int *const_pointer = pointer;
    set.count(const_pointer); // doesn't work
    set.count(const_cast<int *>(const_pointer)); // works fine

    return 0;
}

我在 C++11 中使用 g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0

有没有办法避免丑陋的const_cast&lt;&gt;?这个错误对我来说似乎并不重要......

【问题讨论】:

  • 你知道const int *int * const的区别吗?在您的示例中,const_pointer 不是常量指针,而是指向常量的指针。
  • 由于指针不会用于比较以外的任何事情,我会说const_cast 在这种情况下是有效的,而不是“丑陋”。也许您可以为您的特定集合创建自己的contains,该集合需要一个 const 指针并在内部进行强制转换?
  • @Brian 是的,我知道区别。可能这个问题的措辞有点糟糕......在*后面添加const不会改变行为(无论如何它都隐含在函数调用中)
  • @simon A contains 函数在我的情况下实际上没有意义,因为我想在一个名为 isConnected(const Node *const otherNode) { return ...;} 的函数中使用它,并且在这个意义上已经是包装器本身:D 考虑 const_cast 作为valid 完全没问题,虽然我想避免它(我对 C++ 很陌生,只有大约 2 周,之前主要使用 Java)
  • 你能把设置改成std::unordered_set&lt;int const*&gt; set {};吗?

标签: c++ c++11 constants std


【解决方案1】:

在我看来,这是 C++ 的一个限制。

尽管int*const int* 之间显然存在一个微不足道的相等比较,但关联容器的机制并不“知道”这一点,除非您为您的地图设置了transparent comparator

对于像您这样的无序关联容器,您还需要一个透明哈希(类似原理)。

在这种情况下,老实说,为了简单起见,我会坚持使用const_cast

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-27
    • 1970-01-01
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 2014-01-07
    • 2015-10-11
    • 1970-01-01
    相关资源
    最近更新 更多