Reputation: 721
Suppose you have a set of pointers (yeah...) :
std::set<SomeType*> myTypeContainer;
Then suppose that you want to search this set from a const method of SomeType:
bool SomeType::IsContainered() const
{
return myTypeContainer.find(this) != myTypeContainer.end();
}
This doesn't work. The this
ptr in the method is a const SomeType *const
, which I can't put into the find
. The issue being that find
takes a const-ref, which in this case would mean that the passed pointer is treated as const, but not the thing it points to.
Is there a way to resolve this smoothly (without changing the set template type)?
Upvotes: 12
Views: 1217
Reputation: 18081
In order to enable "mixed" comparison in an ordered container, you can use a key_compare
type that declares the typename key_compare::is_transparent
.
The default comparison functor class of set is std::less<Key>
. It is not "transparent". But std::less<void>
is "transparent" and performs the comparison of any arguments a
and b
as long as a<b
is well formed. So you could define your own comparison functor type or you could use std::less<void>
(or equivalently std::less<>
):
set<SomeType*,std::less<>> myTypeContainer;
Upvotes: 16
Reputation: 173014
As you said, in the const member function this
becomes const SomeType *
(i.e. pointer to const), it can't be implicitly converted to SomeType *
(i.e. pointer to non-const), which is the expected parameter type of find
.
You could use const_cast
to perform explicit conversion.
bool SomeType::IsContainered() const
{
return myTypeContainer.find(const_cast<SomeType *>(this)) != myTypeContainer.end();
}
It would be safe if the cast result is not used for modifying; while std::set::find
won't do that.
Upvotes: 10