Не удается передать const const const const в const ref

Предположим, у вас есть набор указателей (да...):

std::set<SomeType*> myTypeContainer;

Затем предположим, что вы хотите выполнить поиск этого набора из метода const метода SomeType:

bool SomeType::IsContainered() const
{
    return myTypeContainer.find(this) != myTypeContainer.end();
}

Это не работает. this PTR в методе является const SomeType *const, что я не могу поставить в find. Проблема заключается в том, что find принимает const-ref, что в данном случае означает, что переданный указатель рассматривается как const, но не тот, на который он указывает.

Есть ли способ разрешить это плавно (без изменения типа шаблона набора)?

Ответ 1

Как вы сказали, в функции-член const this становится const SomeType * (т.е. указателем на const), он не может быть неявно преобразован в SomeType * (т.е. указатель на не const), который является ожидаемым типом параметра find.

Вы можете использовать const_cast для выполнения явного преобразования.

bool SomeType::IsContainered() const
{
    return myTypeContainer.find(const_cast<SomeType *>(this)) != myTypeContainer.end();
}

Было бы безопасно, если результат отливки не используется для модификации; в то время как std::set::find не сделает этого.

Ответ 2

Для того, чтобы дать возможность "смешанное" сравнению в упорядоченном контейнере, вы можете использовать key_compare тип, который декларирует имяТип key_compare::is_transparent.

Класс функтора сравнения по умолчанию - std::less<Key>. Это не "прозрачно". Но std::less<void> является "прозрачным" и выполняет сравнение любых аргументов a и b пока a<b хорошо сформирован. Таким образом, вы можете определить свой собственный тип функционала сравнения, или вы можете использовать std::less<void> (или эквивалентно std::less<>):

set<SomeType*,std::less<>> myTypeContainer;