Почему я не могу const_cast вернуть оператор преобразования? - PullRequest
2 голосов
/ 13 июля 2009

У меня есть оператор преобразования, который возвращает указатель 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);
}

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

Ответы [ 5 ]

4 голосов
/ 13 июля 2009

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

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

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

2 голосов
/ 13 июля 2009

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

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

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

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

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

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

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

1 голос
/ 13 июля 2009

Думайте о 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*() );
1 голос
/ 13 июля 2009

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

0 голосов
/ 13 июля 2009

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

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

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

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

const int* operator () {
...