简体   繁体   中英

Can't pass 'const pointer const' to const ref

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)?

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;

As you said, in the const member function this becomes const SomeType * (ie pointer to const), it can't be implicitly converted to SomeType * (ie 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM