为什么我不能const_cast返回转换运算符?

时间:2022-05-19 21:08:16

I've got a conversion operator that returns a const pointer, and I need to const_cast it. However, that doesn't work, at least under MSVC8. The following code reproduces my problem:

我有一个返回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);
}

Why is that? It seems counter-intuitive. Thanks!

这是为什么?这似乎违反直觉。谢谢!

5 个解决方案

#1


To make it work you have to do :

为了使它工作,你必须做:

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

When you const_cast directly, the compiler look for the cast operator to int*.

直接const_cast时,编译器会将转换运算符查找为int *。

#2


const_cast can only change the constness of a type. If you want to call the implicit operator you have you need a static_cast and then a const_cast. While it's annoying it makes sure you are explicit in what you are doing.

const_cast只能更改类型的常量。如果要调用隐式运算符,则需要static_cast,然后需要const_cast。虽然它很烦人,但它确保你明确你在做什么。

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

You can also use the old school c-style cast operator

您也可以使用旧学校的C型演员

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

But this is highly discouraged for several reasons:

但出于以下几个原因,这是非常沮丧的:

  • It isn't grepable
  • 它不易受影响

  • You can very easily do more than you intended. Most of the time you don't want to mess with const_cast type operations and using static_cast enforces this. In fact you very rarely want a const_cast. If you find yourself doing it regularly you have some design mistakes.
  • 您可以轻松地完成比预期更多的工作。大多数情况下,您不希望混淆const_cast类型的操作,并使用static_cast强制执行此操作。事实上,你很少想要一个const_cast。如果你发现自己经常这样做,你会遇到一些设计错误。

Edit: I was slightly off, I fixed it now. It makes the c-style cast a little uglier

编辑:我稍微偏了,我现在修好了。它使得c风格的演员有点丑陋

#3


You can only use const_cast to convert to a non-const pointer of the same type (to cast away constness). To cast between unrelated types you need reinterpret_cast.

您只能使用const_cast转换为相同类型的非const指针(以抛弃constness)。要在不相关的类型之间进行转换,您需要reinterpret_cast。

#4


Think of const_cast<> as a function template

将const_cast <>视为函数模板

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

(that's not how it's implemented, but it helps here to imagine it was). Then Source is deduced as MyClass, and there's nothing const_cast can do to get an int* from a MyClass.

(这不是它的实现方式,但它有助于想象它是)。然后Source被推断为MyClass,并且const_cast没有什么可以从MyClass获取int *。

What you want is either of the following:

你想要的是以下任何一种:

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

#5


Probably it would be clearer to your compiler if you do something like:

如果您执行以下操作,可能会更清楚您的编译器:

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

I haven't tried yet, thought.

我还没有尝试过,想过。

EDIT: Shouldn't the operator declaration be something like:

编辑:操作员声明不应该是这样的:

const int* operator () {

#1


To make it work you have to do :

为了使它工作,你必须做:

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

When you const_cast directly, the compiler look for the cast operator to int*.

直接const_cast时,编译器会将转换运算符查找为int *。

#2


const_cast can only change the constness of a type. If you want to call the implicit operator you have you need a static_cast and then a const_cast. While it's annoying it makes sure you are explicit in what you are doing.

const_cast只能更改类型的常量。如果要调用隐式运算符,则需要static_cast,然后需要const_cast。虽然它很烦人,但它确保你明确你在做什么。

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

You can also use the old school c-style cast operator

您也可以使用旧学校的C型演员

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

But this is highly discouraged for several reasons:

但出于以下几个原因,这是非常沮丧的:

  • It isn't grepable
  • 它不易受影响

  • You can very easily do more than you intended. Most of the time you don't want to mess with const_cast type operations and using static_cast enforces this. In fact you very rarely want a const_cast. If you find yourself doing it regularly you have some design mistakes.
  • 您可以轻松地完成比预期更多的工作。大多数情况下,您不希望混淆const_cast类型的操作,并使用static_cast强制执行此操作。事实上,你很少想要一个const_cast。如果你发现自己经常这样做,你会遇到一些设计错误。

Edit: I was slightly off, I fixed it now. It makes the c-style cast a little uglier

编辑:我稍微偏了,我现在修好了。它使得c风格的演员有点丑陋

#3


You can only use const_cast to convert to a non-const pointer of the same type (to cast away constness). To cast between unrelated types you need reinterpret_cast.

您只能使用const_cast转换为相同类型的非const指针(以抛弃constness)。要在不相关的类型之间进行转换,您需要reinterpret_cast。

#4


Think of const_cast<> as a function template

将const_cast <>视为函数模板

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

(that's not how it's implemented, but it helps here to imagine it was). Then Source is deduced as MyClass, and there's nothing const_cast can do to get an int* from a MyClass.

(这不是它的实现方式,但它有助于想象它是)。然后Source被推断为MyClass,并且const_cast没有什么可以从MyClass获取int *。

What you want is either of the following:

你想要的是以下任何一种:

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

#5


Probably it would be clearer to your compiler if you do something like:

如果您执行以下操作,可能会更清楚您的编译器:

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

I haven't tried yet, thought.

我还没有尝试过,想过。

EDIT: Shouldn't the operator declaration be something like:

编辑:操作员声明不应该是这样的:

const int* operator () {