My problem is illustrated by following example:
#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);
}
Compilation ends in:
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)
I know why it does not compile, but is there any solution less ugly and brutal than s.find((A*)cp)
? Both set and const pointer are given.
An option is to use C++14 transparent operator functors together with heterogeneous lookup:
std::set<A*, std::less<>> s;
s.find(cp);
Unfortunately, heterogeneous lookup is not currently supported in libstdc++, but it's marked as WIP. (It's available in clang/libc++ and will be available in the next version of Visual Studio.) Without it, you are pretty much stuck with const_cast
'ing cp
.
Tragically, set
's querying methods aren't templated on the key type (they really should be), so lower_bound
, equal_range
, etc. won't help.
Your only options, assuming that the variable types aren't negotiable, are to cast away the pointer's constness, or reinterpret_cast
the set to a set<const A*>
. The latter in some ways feels nicer to me, but it's technically unsafe.
Cast away the constness. Use const_cast
to do it, to make it clear that that's the only thing the cast is doing. If you like, wrap that and the find in a free function; if a piece of code is being evil, it's a good idea to make the evil thing the only thing it does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With