Избегание const_cast при вызове std:: set <Type *>:: find

Есть ли хороший способ избежать const_cast ниже, сохраняя при этом константную корректность?

Без 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();
   }
};

Ответ 2

Я хочу объяснить основную логику, почему это невозможно.

Предположим, что 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 int* в int* без выполнения const_cast.

Ответ 3

Если вы хотите сохранить const int* s, сохраните const int* s. Если вы хотите сохранить int* вместо этого, сделайте это, но вы не можете смешивать и сопоставлять это (по крайней мере, не без взлома, который вы уже использовали).

Выберите один и придерживайтесь его.

Ответ 4

Есть ли хороший способ избежать const_cast ниже, сохраняя константную корректность?

Я не уверен, что то, что я собираюсь предложить, квалифицируется как "хороший способ". Однако вы можете избежать 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;
}