2

いいえ。この質問は 、static_cast、dynamic_cast、const_cast、および reinterpret_cast を使用する必要がある場合の重複ではありません。

ここでの質問は、重複として説明されているリンクとはまったく異なります。

最初の質問: 以下の 2 つのケースで const_cast を使用しています。そのうちの1つが機能します。もう一方はそうではありません。

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);

2 番目の質問: すべてのキャストは、ポインターと参照に対してのみ使用できますか? 次の例は、ポインターまたは参照が画像にない場合は無効ですか?

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.
4

2 に答える 2

3

const_castオブジェクトではなくに適用され、それ自体もです。

§ 5.2.11 [expr.const.cast]/p1:

式の結果のconst_cast<T>(v)型はTです。オブジェクト型への左辺値参照の場合T、結果は左辺値です。オブジェクト型への右辺値参照の場合T、結果は xvalue です。それ以外の場合、結果は prvalue であり、左辺値から右辺値 (4.1)、配列からポインター (4.2)、および関数からポインター (4.3) への標準変換が式に対して実行されます。v

  1. const_cast<int*>(i)=m;

代入の左側にはprvalue値カテゴリがあり、int*prvalue は代入をサポートしていないため、この呼び出しは無効です。正しい構文は になりますがconst_cast<int*&>(i)=m;、このi例では が宣言されconstているため、未定義の動作†</sup> が呼び出されます。

  1. const_cast<int*>(*i1)=l;

型のポインターを逆参照すると、左辺値値カテゴリの式が作成されます。キャスト式は割り当ての左側にあるため、int*左辺値参照型へのキャストである必要があります。)。const_cast<int&>(*i1)=10;i1const

  1. const_cast<int>(a)=b;

部分自体は有効です。const_cast<int>(a)特に、ポインター型でも参照型でもないオブジェクトを表す式に const_cast を適用できます。しかし、割り当ての左側にあるため、コンパイルされません。に変更しても、宣言されconst_cast<int&>(a)=b;ているため、未定義の動作がトリガーされます†</sup>。aconst


†</sup> § 7.1.6.1 [dcl.type.cv]/p4:

ミュータブル (7.1.1) と宣言されたクラス メンバーを変更できることを除いて、その有効期間中 (3.8) に const オブジェクトを変更しようとすると、未定義の動作が発生します。

于 2015-08-18T12:01:18.247 に答える
2

最初の答え:あなたの例では、コンパイラにこのように解釈できる何かを強制しようとしています

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

ここで本当にやりたいことは、const ではないポインターを逆参照することです。そのため、次のようにする必要があります。

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

2 番目の回答const_cast:未定義の動作につながるため、値を const することは禁止されています。実際には最後にない何かを指すポインターまたは参照から constness を削除することのみが許可されconst、ポインターのみがその値を変更することを許可しません。

この問題は、この回答で驚くほど説明されています。

于 2015-08-18T11:46:43.513 に答える