Почему я не могу const_cast возвращать значение оператора преобразования?

StackOverflow https://stackoverflow.com/questions/1119375

  •  12-09-2019
  •  | 
  •  

Вопрос

У меня есть оператор преобразования, который возвращает указатель const, и мне нужно его const_cast .Однако это не работает, по крайней мере, в MSVC8.Следующий код воспроизводит мою проблему:

class MyClass {
public:
    operator const int* () {
        return 0;
    }
};

int main() {
    MyClass obj;
    int* myPtr;
    // compiles
    const int* myConstPtr = obj;
    // compiles
    myPtr = const_cast<int*>(myConstPtr);
    // doesn't compile (C2440: 'const_cast' : cannot convert from 'MyClass' to 'int *')
    myPtr = const_cast<int*>(obj);
}

Почему это?Это кажется нелогичным.Спасибо!

Это было полезно?

Решение

Чтобы это сработало, вы должны сделать :

myPtr = const_cast<int*>(static_cast<const int*>(obj));

Когда вы выполняете const_cast напрямую, компилятор ищет оператор приведения к int*.

Другие советы

const_cast может изменять только константу типа.Если вы хотите вызвать неявный оператор, который у вас есть, вам нужен static_cast и затем a const_cast.Хотя это раздражает, это гарантирует, что вы четко представляете, что делаете.

myPtr = const_cast<int*>(static_cast<const int*>(obj));

Вы также можете использовать оператор приведения в стиле старой школы c

myPtr = (int*)(const int*)obj;

Но это крайне не рекомендуется по нескольким причинам:

  • Это невозможно исправить
  • Вы очень легко можете сделать больше, чем намеревались.Большую часть времени вы не хотите связываться с const_cast операции ввода и использование static_cast обеспечивает соблюдение этого.На самом деле вы очень редко хотите const_cast.Если вы поймаете себя на том, что делаете это регулярно, у вас возникнут некоторые ошибки в дизайне.

Редактировать:Я был немного не в себе, сейчас я это исправил.Это делает актерский состав в стиле с немного уродливее

Вы можете использовать const_cast только для преобразования в неконстантный указатель того же типа (чтобы отбросить константу).Для приведения между несвязанными типами вам нужно reinterpret_cast .

Подумайте о const_cast<> в качестве шаблона функции

template <typename Target, typename Source>
Target const_cast( Source src );

(это не так реализовано, но здесь помогает представить, как это было).Тогда Source выводится как MyClass, и там ничего нет const_cast можно сделать, чтобы получить int * из MyClass.

То, что вы хотите, - это одно из следующих действий:

const_cast<int*>( static_cast<const int*>(obj) /* invokes operator const int* */ );
// or
const_cast<int*>( obj.operator const int*() );

Вероятно, вашему компилятору было бы понятнее, если бы вы сделали что-то вроде:

myPtr = const_cast<int*>(obj());

Я еще не пробовал, подумал.

Редактировать:Разве объявление оператора не должно быть чем-то вроде:

const int* operator () {
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top