Метод find для набора значений, не содержащих констант, не может быть вызван со значениями const. Можно ли использовать const_cast для решения этой проблемы? - PullRequest
4 голосов
/ 19 июня 2020

Допустим, p ниже должен быть указателем на const X. Тогда невозможно вызвать find для набора указателей на X с моим специальным классом сравнения. Это недостаток слов «набор» и «найти»? Безопасно ли решить эту проблему с помощью const_cast, как это сделал я?

struct X{
    std::string key;
    X(std::string s): key(s) {}
};
struct compare {
    bool operator() (const X* lhs, const X* rhs) const {
        return lhs->key < rhs->key;
    }
};
int main() {
    std::set<X*,compare> m;
    const X a("hello");
    const X*p=&a;
    std::set<X*,compare>::const_iterator it=m.find(const_cast<X*>(p));
}

1 Ответ

4 голосов
/ 19 июня 2020

Это использование const_cast безопасно, но любое использование const_cast пугает. const_cast допустимо до тех пор, пока вы не изменяете объект посредством преобразования, чего не делает std::set::find.

Однако здесь const_cast не требуется. Если вы сделаете свой компаратор прозрачным , это позволит разрешить find поиск на основе чего-либо, сопоставимого с типом ключа . Это именно то, что мы хотим:

struct compare {
    using is_transparent = void; // doesn't matter which type you use

    bool operator() (const X* lhs, const X* rhs) const {
        // You might want to consider using std::less<X*> to compare these.
        // std::less<T*> can compare pointers which are not part of the
        // same array, which is not allowed with just a simple less-than
        // comparison.
        return lhs->key < rhs->key;
    }
};

Полный пример: https://godbolt.org/z/NsZccs

...