Почему я не могу const_cast возвращать значение оператора преобразования?
-
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 () {