使用constcast去掉constness
casting away the constness using const_cast
否。此问题与应在何时使用static_cast、dynamic_cast、const_cast和relpret_cast?
这里提出的问题与被描述为重复的链接完全不同。
第一个问题:我在下面的两种情况下使用const_cast。其中一个有效。另一个没有。
1. int*const//有效。
在这种语法中,变量将指向的地址不能更改。所以我使用了如下的const_cast,它很有效:
`
int j=3;
int *k=&j;
int *m=&j;
int* const i=k;
const_cast<int*>(i)=m; //OK: since i=m would not work so cast is necessary`
2.const int*//不起作用。
被指向的地址可以更改,但值不能更改(尽管可以通过使变量指向不同的地址来更改(。我使用的const_cast在这里似乎不起作用:
`
int j=9;
int *k=&j;
const int* i1=0;
i1=k; //OK
//*i1=10;//ERROR.`
所以我试着通过各种方式打字如下,但没有任何效果:
const_cast<int*>(i1)=10;
const_cast<int*>(*i1)=l;
*i1=const_cast<int>(l);
*i1=const_cast<int*>(10);
第二个问题:是否所有的强制转换都只适用于指针和引用?以下示例在图片中没有指针或引用的情况下无效吗?
const int a=9;
int b=4;
const_cast<int>(a)=b; //cannot convert from 'int' to 'int'. why is compiler
//trying to convert from int to int anyways or fails
//when both the types are same.
const_cast
应用于表达式,而不是对象,并且它本身也是的表达式:
§5.2.11【expr.const.cast】/p1:
表达式CCD_ 2的结果是类型CCD_。如果
T
是对对象类型的左值引用,则结果是一个左值;如果T
是对对象类型的右值引用,则结果为x值;否则,结果是一个prvalue和左值到右值(4.1(、数组到指针(4.2(和函数到指针(4.3(的标准对表达式v
执行转换
const_cast<int*>(i)=m;
此调用无效,因为赋值的左侧具有prvalue值类别,而int*
prvalue不支持赋值。正确的语法是const_cast<int*&>(i)=m;
,但由于示例中的i
被声明为const
,它将调用未定义的行为†。
const_cast<int*>(*i1)=l;
取消引用类型为int*
的指针将创建一个左值值类别的表达式,并且由于强制转换表达式位于赋值的左侧,因此它应该强制转换为左值引用类型,即const_cast<int&>(*i1)=10;
(前提是i1
指向的任何内容都未声明为const
(。
const_cast<int>(a)=b;
const_cast<int>(a)
部分本身是有效的,特别是您可以将const_cast应用于表示既不是指针类型也不是引用类型的对象的表达式。但由于它位于赋值的左侧,因此不会进行编译。即使将其更改为const_cast<int&>(a)=b;
,也会触发未定义的行为,因为const_cast<T>(v)
0被声明为const
†。
†§7.1.6.1[dcl.type.cv]/p4:
除了任何声明为可变的类成员(7.1.1(都可以修改外,任何修改常量的尝试对象在其生存期内(3.8(会导致未定义的行为。
第一个答案:在您的示例中,您试图强制编译器执行一些可以像一样解释的操作
const_cast<int*>(i1)=10; //int* = int: assign address to pointer
const_cast<int*>(*i1)=l; //const_cast<int*>(int): cast the value under pointer to pointer
*i1=const_cast<int>(l); //const_casting from const values is forbidden
*i1=const_cast<int*>(10); //10 is an rvalue
在这里,您真正想做的是取消引用一个不再是常量的指针。这就是为什么你需要这样做:
int j = 9;
int *k = &j;
const int* i1 = 0;
i1 = k;
*(const_cast<int*>(i1)) = 10;
相当于
int j = 9;
int *k = &j;
const int* i1 = 0;
i1 = k;
int* temp = const_cast<int*>(i1); //you get rid of 'const'...
*temp = 10; //...and now you assign value as you wanted to - this operation became available
第二个答案:禁止const_cast
常量值,因为它会导致未定义的行为。只允许从指向最终不是const
的指针或引用中删除常量,并且只有指针不允许修改其值。
这个问题在这个答案中得到了令人敬畏的描述。
- 找到所有与自己求和的数字X的快速方法,去掉一个数字得到N
- 基于范围的自定义迭代器:constness问题
- 去掉库中的全局变量
- 三色图算法和constness
- reduce函数的第二个rhs参数中tbb::parallel_reduce:constness的Lambda形式
- 去掉doxygen的点?
- 从嵌入式C/C++逻辑中去掉goto语句
- 在C++中去掉CString中的换行符
- 在C++中使用-binary运算符从变量中去掉int时发出警告.原因是什么
- 使用decltype和constness的C++11尾部返回成员函数
- 将函数参数的"constness"复制到其返回类型 C++
- 虽然我们用大O表示法去掉常量,但在现实生活中这是否重要
- 把rect分成水平部分,去掉第一部分
- 在move构造函数中去掉constness可以接受吗
- C++去掉前导零
- Regex去掉前导零
- 能够使用static_cast why消除constness
- SIMD倾向于总是去掉分支
- 去掉if-else并在c++中切换
- 使用constcast去掉constness