const_cast 変換
異なるcv修飾子を持つ型間で変換を行います。
目次 |
[編集] 構文
const_cast< ターゲット型 >( 式 ) |
|||||||||
ターゲット型の値を返します。
[編集] 説明
const_castで可能な変換は以下の通りです。
T1とT2について、T1とT2がcv修飾子のみが異なる場合(形式的には、両方の型の修飾子分解を考慮し、すべてのiについてP1_iがP2_iと同じである場合)、型T1のprvalueはT2に変換できます。- 式がヌルポインタ値である場合、結果もヌルポインタ値です。
- 式がヌルメンバポインタ値である場合、結果もヌルメンバポインタ値です。
- 式がオブジェクトを指している場合、結果は同じオブジェクトを指します。
- 式がオブジェクトの末尾を指している場合、結果は同じオブジェクトの末尾を指します。
- 式がデータメンバを指している場合、結果は同じデータメンバを指します。
|
式がprvalueであっても、一時的な実体化は行われません。 |
(C++17以降) |
T1とT2について、T1へのポインタがconst_cast<T2*>を使って型「T2へのポインタ」に明示的に変換できる場合、以下の変換も可能です。- 型
T1のlvalueは、const_cast<T2&>を使って型T2のlvalueに明示的に変換できます。
|
(C++11以降) |
|
結果の参照は元のオブジェクトを参照します。 |
(C++17まで) |
|
式がglvalueの場合、結果の参照は元のオブジェクトを参照します。そうでなければ、結果の参照は実体化された一時オブジェクトを参照します。 |
(C++17以降) |
すべてのキャスト式と同様に、結果は次のようになります。
- ターゲット型がlvalue参照型である場合、または関数型へのrvalue参照である場合、lvalueになります (C++11以降)。
|
(C++11以降) |
- それ以外の場合はprvalueになります。
[編集] const性の除去
2つの異なる型T1とT2について、T1からT2への変換は、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コンポーネント)に変換する修飾子変換が存在しない場合、const性を除去する (casts away constness) と言います。
型T1*のprvalueから型T2*へのキャストがconst性を除去する場合、型T1の式からT2への参照へのキャストもconst性を除去します。
const性を除去するにはconst_castのみを使用できます。
「const性を除去する」は「揮発性を除去する」ことを意味します。これは、修飾子変換が揮発性を除去できないためです。
[編集] 備考
関数へのポインタおよびメンバ関数へのポインタはconst_castの対象ではありません。
const_castは、実際にはconstオブジェクトを参照している非const型の参照またはポインタ、あるいは実際にはvolatileオブジェクトを参照している非volatile型の参照またはポインタを形成することを可能にします。非constアクセスパスを介してconstオブジェクトを変更したり、非volatileなglvalueを介してvolatileオブジェクトを参照したりすると、未定義の動作を引き起こします。
[編集] キーワード
[編集] 例
#include <iostream> struct type { int i; type(): i(3) {} void f(int v) const { // this->i = v; // compile error: this is a pointer to const const_cast<type*>(this)->i = v; // OK as long as the type object isn't const } }; int main() { int i = 3; // i is not declared const const int& rci = i; const_cast<int&>(rci) = 4; // OK: modifies i std::cout << "i = " << i << '\n'; type t; // if this was const type t, then t.f(4) would be undefined behavior t.f(4); std::cout << "type::i = " << t.i << '\n'; const int j = 3; // j is declared const [[maybe_unused]] int* pj = const_cast<int*>(&j); // *pj = 4; // undefined behavior [[maybe_unused]] void (type::* pmf)(int) const = &type::f; // pointer to member function // const_cast<void(type::*)(int)>(pmf); // compile error: const_cast does // not work on function pointers }
出力
i = 4 type::i = 4
[編集] 欠陥レポート
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 1965 | C++11 | const_castは配列prvalueへのrvalue参照をバインドできませんでした | そのような参照をバインドできるようになりました |
| CWG 2879 | C++17 | ポインタprvalueオペランドは実体化されました | それらは実体化されません |
[編集] 参照
- C++23標準 (ISO/IEC 14882:2024)
- 7.6.1.11 Const cast [expr.const.cast]
- C++20 standard (ISO/IEC 14882:2020)
- 7.6.1.10 Const cast [expr.const.cast]
- C++17 standard (ISO/IEC 14882:2017)
- 8.2.11 Const cast [expr.const.cast]
- C++14 standard (ISO/IEC 14882:2014)
- 5.2.11 Const cast [expr.const.cast]
- C++11 standard (ISO/IEC 14882:2011)
- 5.2.11 Const cast [expr.const.cast]
- C++98 標準 (ISO/IEC 14882:1998)
- 5.2.11 Const cast [expr.const.cast]
- C++03 標準 (ISO/IEC 14882:2003)
- 5.2.11 Const cast [expr.const.cast]