调用 std::set<Type*>::find 时避免使用 const_cast

Avoiding const_cast when calling std::set<Type*>::find

有没有什么好的方法可以避免下面的 const_cast,同时保持 const 的正确性?

如果没有 const_cast,下面的代码将无法编译。 set::find 获取对集合的键类型的 const 引用,因此在我们的例子中它保证不会更改传入的指针值;但是,它不能保证不会更改指针指向的内容。

class C {
public:
   std::set<int*> m_set;

   bool isPtrInSet(const int* ptr) const
   {
       return m_set.find(const_cast<int*>(ptr)) != m_set.end();
   }
};

Is there any good way to obviate the const_cast below, while keeping const correctness?

我不确定我要提出的建议是否符合 "good way"。但是,如果您不介意自己迭代集合的内容,则可以避免使用 const_cast。请记住,这会将 O(log(N)) 操作转换为 O(N) 操作。

bool isPtrInSet(const int* ptr) const
{
   for ( auto p : m_set )
   {
      if ( p == ptr )
      {
         return true;
      }
   }
   return false;
}

我想解释为什么这是不可能的基本逻辑。

假设 set<int*>::find(const int*) 是合法的。然后您可以执行以下操作:

set<int*> s;
const int* p_const;
// fill s and p
auto it = s.find(p_const);
int* p = *it;

嗨,太棒了!您在未执行 const_cast.

的情况下将 const int* 转换为 int*

.

在 C++14 中,您可以使用自己的比较器,将 int const* 声明为 transparent。这将启用 template overload of find() that can compare keys against arbitrary types. See this related SO question. And here's Jonathan Wakely's explanation.