为什么const_cast需要说明你要投射的内容?

问题描述:

根据标准(第5.2.11节),一个const_cast将cv-qualifiers(const或volatile)转换掉。为什么const_cast需要说明你要投射的内容?

下面是一个简单的例子。首先声明两个函数采用指针和参考:使用适当的const_cast

Bar b; 
const Bar& cb = b; 

,然后你可以调用函数:

class Bar { ... }; 
void foo_ptr(Bar*); 
void foo_ref(Bar&); 

然后创建一个参考给const

foo_ptr(const_cast<Bar*>(&cb)); 
foo_ref(const_cast<Bar&>(cb)); 

这是我的问题:因为const_cast无法完成其他演员设计的内容,所以您投射的内容不是很明显吗?换句话说,为什么不语让我简单地说:

foo_ptr(const_cast<>(&cb)); 
foo_ref(const_cast<>(cb)); 

我能想到的只有以下两个原因:

一)编译器应该停止我,当我尝试做一些发疯一样:

foo_ptr(const_cast<int*>(&cb)); 
foo_ref(const_cast<int&>(cb)); 

并迫使我明确指出我铸造它,然后可以让我从行为不端的类型。我觉得这个(假设的)解释很弱,因为如果语言倾向于让我写下错误只是为了让编译器纠正我,那将是很奇怪的。

b)如果变量既是常量又是易失性的,则可能存在歧义。在这种情况下,编译器将无法告诉我是否试图抛弃这一个或另一个(或两者)。

这是为什么,还是有其他原因?

const_cast可用于添加或删除constvolatile限定符。所以,如果这样的语法被允许,以下所有的将是const_cast<>(&cb)合法目标类型:

Bar*     (1) 
const Bar*   (2) 
volatile Bar*  (3) 
const volatile Bar* (4) 

您打算(1)(2)通常很愚蠢,但可以想象,它可能发生在某处,也许在某些模板代码中。 (3)(4)的确存在以下问题:您可以删除const资格,并将所有资格都添加到单个演员表中。

你可以用一对石膏,const_castvolatile_cast和的取代现有const_cast,和禁止的情况下(2);那么你可以使用它们中的任何一个而不使用目标类型。然而,知道演员表达的类型则更加困难。要知道演员表达式是否添加或删除限定条件,您必须知道源表达式的类型。

没有理由你不能使用函数模板来获得你想要的东西:

template <typename T> 
T* remove_const(const T* p) { 
    return const_cast<T*>(p); 
} 

你可以很容易地编写remove_volatileadd_constadd_volatile类似的功能,这两者都是隐含的。

+0

当然,该运算符还允许`const_cast (&b)`(其中b不是`const')和相同的结果类型集合,所以即使它没有处理波动性,您也必须问Alexandros无论const_cast 是否应该切换常量或默认添加或删除它(后者会使它有点用词不当)。正如你所说,在模板中,通常需要在不知道开始的情况下获得const或非const类型。 – 2010-12-08 03:07:21

+0

@Tony:关于b不需要是const的好处。更一般地说,尽管我知道const_cast也可以添加const,但我的隐含假设是没有人这样做(因为还有其他方法可以这样做),因此如果输入b不是const,那么就让它成为。 – 2010-12-08 03:22:35

我认为詹姆斯麦克奈利斯已经谈到了重要的原因。 const_cast都可以并删除常量/不稳定性。这并不总是清楚你想要什么。

如果我打电话const_castconst foo类型的参数,这是否意味着我想让它不const,或添加volatile呢?或者它应该只是保留const限定符?如果我在类型(非const)foo的对象上调用它,它应该添加const吗?还是应该假设我想删除常量,并返回一个类型为(非常量)foo的对象呢?

另一个原因可能只是一致性。

我们有static_cast<T>(x),dynamic_cast<T>(x),reinterpret_cast<T>(x)所以如果没有类似于模板的语法就有const_cast(x),看起来很奇怪。

的主要原因是使用const_cast你可以从

Foo * const * volatile * * 

转换为

Foo * * * volatile * const 

是否真的明显的目标类型是什么?