Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

Without const_cast the code below doesn't compile. set::find gets a const reference to the set's key type, so in our case it guarantees not to change the passed-in pointer value; however, nothing it guaranteed about not changing what the pointer points to.

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();
   }
};
like image 826
Danra Avatar asked May 09 '16 14:05

Danra


People also ask

Is const_cast good practice?

As a common rule, it is very often considered a bad practice to use const_cast<>() in C++ code as it reveals (most of the time) a flaw in the design.

What is the use of const_cast in C++?

const_cast is one of the type casting operators. It is used to change the constant value of any object or we can say it is used to remove the constant nature of any object. const_cast can be used in programs that have any object with some constant value which need to be changed occasionally at some point.

Is const_cast safe?

const_cast is safe only if you're casting a variable that was originally non- const . For example, if you have a function that takes a parameter of a const char * , and you pass in a modifiable char * , it's safe to const_cast that parameter back to a char * and modify it.


2 Answers

Yes.

In C++14, you can use your own comparator that declares int const* as transparent. This would enable the template overload of find() that can compare keys against arbitrary types. See this related SO question. And here's Jonathan Wakely's explanation.

like image 150
Arvid Avatar answered Sep 23 '22 05:09

Arvid


I want to explain the underlying logic of why this is impossible.

Suppose set<int*>::find(const int*) would be legitimate. Then you could do the following:

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

Hey presto! You transformed const int* to int* without performing const_cast.

like image 42
user31264 Avatar answered Sep 22 '22 05:09

user31264