const_cast
conversion
異なるcv修飾を持つ型間で変換を行います。
目次 |
構文
const_cast<
target-type
>(
expression
)
|
|||||||||
target-type 型の値を返します。
説明
以下の変換のみが const_cast で実行可能です:
T1
と
T2
について、
T1
型のprvalueは、
T1
と
T2
がCV修飾のみが異なる場合(形式的には、両方の型の
修飾分解
を考慮した場合、すべての
i
について
P1_i
が
P2_i
と同じである場合)、
T2
に変換できます。
- expression がnullポインタ値の場合、結果もnullポインタ値です。
- expression がnullメンバポインタ値の場合、結果もnullメンバポインタ値です。
- expression がオブジェクトを指す場合、結果は同じオブジェクトを指します。
- expression がオブジェクトの終端を過ぎて指す場合、結果は同じオブジェクトの終端を過ぎて指します。
- expression がデータメンバを指す場合、結果は同じデータメンバを指します。
|
expression がprvalueであっても、 一時オブジェクトの実体化 は行われません。 |
(C++17以降) |
T1
と
T2
について、
T1
へのポインタが
const_cast
<
T2
*
>
を使用して「
T2
へのポインタ」型に明示的に変換できる場合、以下の変換も行うことができます:
-
型
T1の左辺値は、 const_cast < T2 & > を使用して型T2の左辺値に明示的に変換できます。
|
(C++11以降) |
|
結果の参照は元のオブジェクトを参照します。 |
(C++17まで) |
|
式 がglvalueの場合、結果の参照は元のオブジェクトを参照します。それ以外の場合、結果の参照は 具体化された一時オブジェクト を参照します。 |
(C++17以降) |
すべてのキャスト式と同様に、結果は次のとおりです:
- target-type が左辺値参照型の場合(または関数型への右辺値参照の場合 (C++11以降) )、左辺値となる;
|
(C++11以降) |
- それ以外の場合は prvalue。
const性の除去
2つの異なる型
T1
と
T2
について、
T1
から
T2
への変換は、
const性を捨てる
場合がある。これは、
T2
の
修飾分解
が「cv2_0 P2_0 cv2_1 P2_1 ... cv2_n−1 P2_n−1 cv2_n U2」の形式であり、かつ
T1
から「cv2_0 P1_0 cv2_1 P1_1 ... cv2_n−1 P1_n−1 cv2_n U1」(同じcv要素、異なるP要素とU要素)への
修飾変換
が存在しない場合である。
T1*型のprvalueから
T1*
型から
T2*
型へのキャストがconst性を除去する場合、
T1
型の式から
T2
への参照へのキャストもconst性を除去します。
const性を取り除くキャストには const_cast のみが使用できます。
「const性の除去」は「volatilityの除去」を意味します。なぜなら、修飾変換はvolatilityを除去することもできないからです。
注記
関数へのポインタおよびメンバ関数へのポインタは、 const_cast の対象にはなりません。
const_cast は、実際には constオブジェクト を参照している非const型への参照またはポインタ、あるいは実際には volatileオブジェクト を参照している非volatile型への参照またはポインタを形成することを可能にします。constオブジェクトを非constアクセス経由で変更すること、およびvolatileオブジェクトを非volatile glvalue 経由で参照することは未定義動作を引き起こします。
キーワード
例
#include <iostream> struct type { int i; type(): i(3) {} void f(int v) const { // this->i = v; // コンパイルエラー: thisはconstへのポインタ const_cast<type*>(this)->i = v; // typeオブジェクトがconstでない限りOK } }; int main() { int i = 3; // iはconstとして宣言されていない const int& rci = i; const_cast<int&>(rci) = 4; // OK: iを変更する std::cout << "i = " << i << '\n'; type t; // もしこれがconst type tの場合、t.f(4)は未定義動作となる t.f(4); std::cout << "type::i = " << t.i << '\n'; const int j = 3; // jはconstとして宣言されている [[maybe_unused]] int* pj = const_cast<int*>(&j); // *pj = 4; // 未定義動作 [[maybe_unused]] void (type::* pmf)(int) const = &type::f; // メンバ関数へのポインタ // const_cast<void(type::*)(int)>(pmf); // コンパイルエラー: const_castは // 関数ポインタでは動作しない }
出力:
i = 4 type::i = 4
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| CWG 1965 | C++11 | const_cast 配列prvalueへの右辺値参照を束縛できなかった | そのような参照の束縛を許可 |
| CWG 2879 | C++17 | ポインタpvalueオペランドは実体化されていた | 実体化されない |
参考文献
- C++23規格 (ISO/IEC 14882:2024):
-
- 7.6.1.11 Const cast [expr.const.cast]
- C++20 標準 (ISO/IEC 14882:2020):
-
- 7.6.1.10 Const cast [expr.const.cast]
- C++17 規格 (ISO/IEC 14882:2017):
-
- 8.2.11 Const cast [expr.const.cast]
- C++14 標準 (ISO/IEC 14882:2014):
-
- 5.2.11 Const cast [expr.const.cast]
- C++11標準 (ISO/IEC 14882:2011):
-
- 5.2.11 Const cast [expr.const.cast]
- C++98標準 (ISO/IEC 14882:1998):
-
- 5.2.11 定数キャスト [expr.const.cast]
- C++03標準 (ISO/IEC 14882:2003):
-
- 5.2.11 Const cast [expr.const.cast]