Implicit conversions
暗黙の変換は、ある型
T1
の式がその型を受け付けないが、他の型
T2
を受け付ける文脈で使用される際に実行されます。具体的には:
-
式が、引数として
T2型のパラメータで宣言された関数を呼び出す際の引数として使用される場合; -
式が、
T2型を期待する演算子のオペランドとして使用される場合; -
T2型の新しいオブジェクトを初期化する場合(T2を返す関数のreturn文を含む); -
式が
switch
文で使用される場合(
T2は整数型); -
式が
if
文またはループで使用される場合(
T2は bool 型)。
プログラムは、
T1
から
T2
への明確な1つの
暗黙の変換シーケンス
が存在する場合にのみ、正しい形式(コンパイル可能)となります。
呼び出される関数または演算子に複数のオーバーロードが存在する場合、
T1
から利用可能な各
T2
への暗黙変換シーケンスが構築された後、
オーバーロード解決
のルールに基づいて、どのオーバーロードをコンパイルするかが決定されます。
注記: 算術式において、二項演算子の被演算子に対する暗黙の変換の変換先の型は、別個の規則によって決定されます: usual arithmetic conversions .
目次 |
変換の順序
暗黙の変換シーケンスは以下の順序で構成されます:
コンストラクタまたはユーザー定義変換関数の引数を考慮する際、許可される標準変換シーケンスは1つだけです(そうでないと、ユーザー定義変換が効果的に連鎖できてしまいます)。ある非クラス型から別の非クラス型への変換では、標準変換シーケンスのみが許可されます。
標準変換シーケンスは、以下の順序で構成されます:
- lvalue-to-rvalue conversion ,
- array-to-pointer conversion , および
- function-to-pointer conversion ;
|
3)
ゼロまたは1つの
function pointer conversion
;
|
(C++17以降) |
ユーザー定義変換は、ゼロまたは1つの非明示的単一引数 converting constructor または非明示的 conversion function の呼び出しで構成されます。
式
e
が
T2
へ暗黙変換可能
であるとは、
T2
が
e
から
コピー初期化
可能である場合、すなわち宣言
T2 t
=
e
;
が(コンパイル可能な)適切な形式である場合を指す。ここで
t
は仮想的な一時変数を表す。これは
直接初期化
(
T2 t
(
e
)
) とは異なり、後者では明示的コンストラクタと変換関数も追加で考慮される点に注意。
コンテキスト変換
|
以下の文脈では、型 bool が期待され、宣言 bool t ( e ) ; が適正であれば(つまり、 explicit T :: operator bool ( ) const ; のような明示的変換関数も考慮される)、暗黙変換が実行される。このような式 e は 文脈的に bool に変換される と言われる。
|
(C++11以降) |
以下の文脈では、文脈固有の型
T
が期待され、クラス型
E
の式
e
は、次の場合にのみ許可されます
|
(C++14まで) |
|
(C++14以降) |
そのような式
e
は、指定された型
T
へ
文脈的に暗黙変換される
と言います。
明示的変換関数は考慮されないことに注意してください。ただし、
bool
への文脈変換では考慮されます。
(C++11以降)
-
delete式
の引数(
Tは任意のオブジェクトポインタ型); -
整数定数式
(リテラルクラスが使用される場合、
Tは任意の整数型またはスコープなし列挙型、選択されたユーザー定義変換関数は constexpr でなければならない); -
switch文の制御式(Tは任意の整数型または列挙型)。
#include <cassert> template<typename T> class zero_init { T val; public: zero_init() : val(static_cast<T>(0)) {} zero_init(T val) : val(val) {} operator T&() { return val; } operator T() const { return val; } }; int main() { zero_init<int> i; assert(i == 0); i = 7; assert(i == 7); switch (i) {} // C++14までエラー(複数の変換関数が存在) // C++14以降OK(両関数とも同じ型intに変換) switch (i + 0) {} // 常に問題なし(暗黙変換) }
値変換
値変換は式の value category を変更する変換です。これらは、式が異なるvalue categoryの式を期待する演算子のオペランドとして現れるときに常に発生します:
- グリーバリューがオペランドとして現れ、そのオペランドにプラバリューを必要とする演算子の対象となる場合、 lvalue-to-rvalue 、 array-to-pointer 、または function-to-pointer 標準変換が適用され、式がプラバリューに変換されます。
|
(C++17以降) |
Lvalue-to-rvalue変換
任意の非関数、非配列型
lvalue
(C++11以前)
任意の非関数、非配列型
glvalue
(C++11以降)
T
は暗黙的に
rvalue
(C++11以前)
prvalue
(C++11以降)
に変換できます:
-
Tがクラス型でない場合、 rvalue (until C++11) prvalue (since C++11) の型はTのCV修飾なしのバージョンである。 -
それ以外の場合、
rvalue
(until C++11)
prvalue
(since C++11)
の型は
Tである。
不完全型からの左辺値から右辺値への変換がプログラムによって要求される場合、そのプログラムは不適格です。
指定されたオブジェクト( lvalue (until C++11) glvalue (since C++11) が参照するオブジェクト)を obj として:
|
(C++11まで) | ||||
|
(C++11以降) |
この変換は、メモリ位置から値を読み出してCPUレジスタに格納する動作をモデル化します。
配列からポインタへの変換
型「
N
個の
T
の配列」または「境界不明の
T
の配列」の
lvalue
または
rvalue
は、「
T
へのポインタ」型の
prvalue
に暗黙的に変換できます。
配列がprvalueの場合、
一時オブジェクト化
が発生します。
(C++17以降)
結果のポインタは配列の最初の要素を指します(詳細は
配列からポインタへの減衰
を参照)。
関数からポインタへの変換
関数型の lvalue は、その関数を指す prvalue ポインタ に暗黙的に変換できます。これは非静的メンバ関数には適用されません。なぜなら、非静的メンバ関数を参照するlvalueは存在しないからです。
一時的な実体化 (Temporary materialization)
任意の完全型
struct S { int m; }; int i = S().m; // member access expects glvalue as of C++17; // S() prvalue is converted to xvalue 一時的な実体化は以下の状況で発生します:
同じ型のprvalueからオブジェクトを初期化する場合( 直接初期化 または コピー初期化 )には、一時的な実体化は発生 しません :そのようなオブジェクトは初期化子から直接初期化されます。これにより「保証されたコピー省略」が確保されます。 |
(C++17以降) |
整数プロモーション
prvalues 小規模な整数型(例: char )およびスコープなし列挙型のprvaluesは、より大きな整数型(例: int )のprvaluesに変換されることがあります。特に、 算術演算子 は int より小さい型を引数として受け付けず、該当する場合、左辺値から右辺値への変換後に整数プロモーションが自動的に適用されます。この変換は常に値を保持します。
以下のセクションで説明する暗黙の変換は integral promotions に分類されます。
与えられたソース型に対して、整数昇格の宛先型は一意であることに注意してください。そして他のすべての変換は昇格ではありません。例えば、 オーバーロード解決 は char -> int (昇格) を char -> short (変換) よりも優先して選択します。
整数型からのプロモーション
bool 型のprvalueは、 int 型のprvalueに変換することができ、 false は 0 に、 true は 1 になります。
ブール型
bool
を除く、整数型
T
の純粋右辺値
val
について:
- val は、 int がビットフィールドのすべての値を表現できる場合、 int 型のprvalueに変換可能である;
- そうでなければ、 val は、 unsigned int がビットフィールドのすべての値を表現できる場合、 unsigned int に変換可能である;
- そうでなければ、 val は、項目(3)で指定された規則に従って変換可能である。
-
もし
Tが char8_t , (C++20以降) char16_t , char32_t または (C++11以降) wchar_t であれば、 val は項目(3)で指定された規則に従って変換可能; -
それ以外の場合、
Tの 整数変換ランク が int のランクより低い場合:
-
-
val
は
int
型のprvalueに変換可能(もし
int
が
Tのすべての値を表現できる場合); - それ以外の場合、 val は unsigned int 型のprvalueに変換可能。
-
val
は
int
型のprvalueに変換可能(もし
int
が
T
が指定された文字型のいずれかである場合)で指定される場合、
val
は、その基盤型のすべての値を表現できる最初の以下の型のprvalueに変換できます:
-
- int
- unsigned int
- long
- unsigned long
|
(C++11以降) |
列挙型からの昇格
基となる型が固定されていないスコープなし enum 型のprvalueは、その値の全範囲を保持できる以下のリストの最初の型のprvalueに変換できます:
- int
- unsigned int
- long
- unsigned long
|
(C++11以降) |
|
基となる型が固定されているスコープなし列挙型の純粋右辺値は、その基となる型に変換できます。さらに、基となる型が整数昇格の対象となる場合、昇格された基となる型に変換できます。オーバーロード解決の目的では、昇格されていない基となる型への変換が優先されます。 |
(C++11以降) |
浮動小数点プロモーション
float 型の prvalue は double 型のprvalueに変換できます。値は変化しません。
この変換は floating-point promotion と呼ばれます。
数値変換
プロモーションとは異なり、数値変換は値を変更する可能性があり、精度の損失が生じる恐れがあります。
整数変換
整数型またはスコープなし列挙型の prvalue は、他の任意の整数型に変換できます。変換が整数昇格に該当する場合、それは変換ではなく昇格となります。
-
変換先の型が符号なしの場合、結果の値は変換元の値を
法
2
n
とする最小の符号なし値となります。ここで n は変換先の型を表現するために使用されるビット数です。
-
- つまり、宛先の型がより広いか狭いかに応じて、符号付き整数は符号拡張 [1] または切り詰められ、符号なし整数はそれぞれゼロ拡張または切り詰められます。
-
変換先の型が符号付きの場合、元の整数が変換先の型で表現可能であれば値は変化しない。それ以外の場合、結果は
実装定義
(C++20まで)
変換先の型のビット数
n
を用いて、元の値を
2
n
で割った剰余に等しい変換先の型の一意な値 (C++20以降) となる (これは 符号付き整数算術オーバーフロー が未定義動作であることとは異なる)。 - 元の型が bool の場合、値 false はゼロに変換され、値 true は変換先の型の値1に変換される (変換先の型が int の場合、これは整数変換ではなく整数プロモーションであることに注意)。
- 変換先の型が bool の場合、これは ブーリアン変換 となる(後述)。
- ↑ これは exact-width integer types に対してのみ要求される2の補数表現が使用されている場合にのみ適用されます。ただし、現在のところC++コンパイラが利用可能なすべてのプラットフォームは2の補数演算を使用していることに注意してください。
浮動小数点変換
|
浮動小数点型の prvalue は、他の任意の浮動小数点型のprvalueに変換できます。 |
(C++23まで) |
|
浮動小数点型の prvalue は、同等またはより高い 浮動小数点変換ランク を持つ他の任意の浮動小数点型のprvalueに変換できます。 標準浮動小数点型の prvalue は、他の任意の標準浮動小数点型のprvalueに変換できます。
|
(C++23以降) |
変換が浮動小数点の昇格に該当する場合、それは変換ではなく昇格です。
- 変換元の値が変換先の型で正確に表現できる場合、値は変更されません。
- 変換元の値が変換先の型で表現可能な2つの値の中間にある場合、結果はそれら2つの値のいずれかになります(どちらになるかは実装定義ですが、IEEE演算がサポートされている場合、丸めモードはデフォルトで 最近接偶数丸め となります)。
- それ以外の場合、動作は未定義です。
浮動小数点-整数変換
浮動小数点型の prvalue は、任意の整数型のprvalueに変換できます。小数部分は切り捨てられます。つまり、小数部分は破棄されます。
- 切り詰められた値が変換先の型に適合できない場合、動作は未定義です(変換先の型が符号なしであっても、剰余演算は適用されません)。
- 変換先の型が bool の場合、これはブーリアン変換です( 後述 を参照)。
整数型またはスコープなし列挙型のprvalueは、任意の浮動小数点型のprvalueに変換できます。可能な場合は結果は正確になります。
- 値が変換先の型に収まるが正確に表現できない場合、最も近い上位表現可能値と最も近い下位表現可能値のどちらが選択されるかは実装定義である。ただしIEEE演算がサポートされている場合、丸めモードはデフォルトで 最近接偶数丸め となる。
- 値が変換先の型に収まらない場合、動作は未定義である。
- ソース型が bool の場合、値 false はゼロに変換され、値 true は1に変換される。
ポインタ変換
null pointer constant は任意のポインタ型に変換でき、その結果はその型のnullポインタ値となります。このような変換( null pointer conversion として知られる)は、修飾された型への単一の変換として許可されており、つまり数値変換と修飾変換の組み合わせとは見なされません。
任意の(オプションでCV修飾された)オブジェクト型
T
への
prvalue
ポインタは、(同一にCV修飾された)
void
へのprvalueポインタに変換できます。結果のポインタは元のポインタ値と同じメモリ位置を表します。
- 元のポインタがヌルポインタ値の場合、結果は変換先の型のヌルポインタ値となります。
型「(cv修飾された可能性のある)
Derived
へのポインタ」のprvalueは、
型「(cv修飾された可能性のある)
Base
へのポインタ」のprvalueに変換できます。
ここで
Base
は
Derived
の
基底クラス
であり、
Derived
は
完全な
クラス型です。
Base
がアクセス不能または曖昧な場合、プログラムは不適格となります。
- ptr が null ポインタ値の場合、結果も null ポインタ値となる。
-
それ以外の場合、
BaseがDerivedの 仮想基本クラス であり、かつ ptr がDerivedと 類似 した型のオブジェクトを指しておらず、そのオブジェクトが 生存期間 内または構築・破棄期間内にない場合、動作は未定義となる。 - それ以外の場合、結果は派生クラスオブジェクトの基本クラス部分オブジェクトへのポインタとなる。
メンバへのポインタ変換
null pointer constant は任意のメンバポインタ型に変換でき、結果はその型の null メンバポインタ値となります。このような変換( null member pointer conversion として知られる)は、修飾された型への単一の変換として許可されており、つまり、数値変換と修飾変換の組み合わせとは見なされません。
「
Base
の型(修飾の有無は問わず)
T
へのメンバポインタ」型の
prvalue
は、「
Derived
の型(同一の修飾を持つ)
T
へのメンバポインタ」型のprvalueに変換できます。ここで
Base
は
Derived
の基底クラスであり、
Derived
は完全なクラス型です。
Base
が
Derived
の非公開、曖昧、または仮想基底クラスである場合、あるいは
Derived
の中間仮想基底クラスの基底クラスである場合、プログラムは不適格となります。
-
Derivedが元のメンバーを含まず、元のメンバーを含むクラスの基底クラスでもない場合、動作は未定義です。 -
それ以外の場合、結果のポインタは
Derivedオブジェクトで逆参照でき、そのDerivedオブジェクトのBase基底サブオブジェクト内のメンバーにアクセスします。
ブール変換
整数型、浮動小数点型、スコープなし列挙型、ポインタ型、およびメンバへのポインタ型の prvalue は、 bool 型のprvalueに変換できます。
値ゼロ(整数型、浮動小数点型、およびスコープなし列挙型の場合)およびヌルポインタとヌルポインタ-to-member値は false になります。その他のすべての値は true になります。
|
直接初期化 の文脈において、 bool オブジェクトは std::nullptr_t 型のprvalue( nullptr を含む)から初期化可能である。結果の値は false となる。ただし、これは暗黙変換とは見なされない。 |
(C++11以降) |
修飾子変換
一般的に言うと:
-
prvalue
型のポインタから
cv修飾
された型
Tへのprvalueは、よりcv修飾された同じ型Tへのポインタのprvalueに変換できます(つまり、const性とvolatile性を追加できます)。 -
cv修飾された型
TのクラスXにおけるメンバーポインタのprvalueは、 よりcv修飾された 型TのクラスXにおけるメンバーポインタのprvalueに変換できます。
「修飾変換」の正式な定義は 以下 に示されています。
類似の型
非公式には、2つの型は、トップレベルのcv修飾を無視した場合に similar であると言います:
- それらが同じ型である場合、または
- 両方がポインタであり、指し示す型が類似している場合、または
- 両方が同じクラスのメンバへのポインタであり、指し示すメンバの型が類似している場合、または
- 両方が配列であり、配列要素の型が類似している場合。
例:
- const int * const * と int ** は類似している;
- int ( * ) ( int * ) と int ( * ) ( const int * ) は類似していない;
- const int ( * ) ( int * ) と int ( * ) ( int * ) は類似していない;
- int ( * ) ( int * const ) と int ( * ) ( int * ) は類似している(同じ型である);
- std:: pair < int , int > と std:: pair < const int , int > は類似していない。
形式的には、型類似性は資格分解(qualification-decomposition)の観点から定義されます。
型
T
の
修飾分解
は、非負の
n
に対して
T
が「
cv_0 P_0 cv_1 P_1 ... cv_n−1 P_n−1 cv_n U
」となるような、コンポーネント
cv_i
と
P_i
の列である。ここで
-
each
cv_iは const と volatile のセットであり、かつ -
each
P_iは
-
- 「〜へのポインタ」、
-
「クラス
C_iの型〜のメンバへのポインタ」、 - 「 N_i 個の要素からなる配列」、または
- 「要素数不明の配列」。
P_i
が配列を指定する場合、要素型のcv修飾子
cv_i+1
は配列のcv修飾子
cv_i
としても扱われます。
// T は「const int へのポインタへのポインタ」であり、3つの修飾分解を持つ: // n = 0 -> cv_0 は空、U は「const int へのポインタへのポインタ」 // n = 1 -> cv_0 は空、P_0 は「ポインタ」、 // cv_1 は空、U は「const int へのポインタ」 // n = 2 -> cv_0 は空、P_0 は「ポインタ」、 // cv_1 は空、P_1 は「ポインタ」、 // cv_2 は「const」、U は「int」 using T = const int**; // 以下のいずれかの型を U に代入すると、いずれかの分解が得られる: // U = U0 -> n = 0 の分解: U0 // U = U1 -> n = 1 の分解: ポインタ [U1] // U = U2 -> n = 2 の分解: ポインタ [ポインタ [const U2]] using U2 = int; using U1 = const U2*; using U0 = U1*;
2つの型
T1
と
T2
は、それぞれに対して修飾分解が存在し、2つの修飾分解に対して以下のすべての条件が満たされる場合、
類似している
とされます:
- それらは同じ n を持つ。
-
Uで示される型は同じである。 -
対応する
P_iコンポーネントはすべての i について同じである または、一方が「 N_i の配列」で他方が「境界未知の配列」である (C++20以降) 。
// n = 2 での修飾分解: // [const intへのvolatileポインタ]へのポインタ using T1 = const int* volatile *; // n = 2 での修飾分解: // [intへのポインタ]へのconstポインタ using T2 = int** const; // 上記2つの修飾分解について // cv_0、cv_1、cv_2はすべて異なるが、 // 同じn、U、P_0、P_1を持つため、 // 型T1とT2は類似している。
cv修飾子の組み合わせ
以下の説明において、型
Tn
の最長修飾分解は
Dn
と表記され、その構成要素は
cvn_i
および
Pn_i
と表記されます。
|
型
二つの型
|
(C++20以前) |
|
二つの型
型
|
(C++20以降) |
// T1の最長修飾分解 (n = 2): // [char]へのポインタへのポインタ using T1 = char**; // T2の最長修飾分解 (n = 2): // [const char]へのポインタへのポインタ using T2 = const char**; // D3のcv3_iとT_iコンポーネントの決定 (n = 2): // cv3_1 = 空 (空のcv1_1と空のcv2_1の和集合) // cv3_2 = "const" (空のcv1_2と"const" cv2_2の和集合) // P3_0 = "pointer to" (未知の境界を持つ配列なし、P1_0を使用) // P3_1 = "pointer to" (未知の境界を持つ配列なし、P1_1を使用) // cv_2以外のすべてのコンポーネントは同じ、cv3_2はcv1_2と異なるため、 // [1, 2)の各kに対してcv3_kに"const"を追加: cv3_1が"const"になる // T3は「const charへのconstポインタへのポインタ」、すなわちconst char* const * using T3 = /* T1とT2の修飾結合型 */; int main() { const char c = 'c'; char* pc; T1 ppc = &pc; T2 pcc = ppc; // エラー: T3はcv修飾されていないT2と同じではない、 // 暗黙変換なし *pcc = &c; *pc = 'C'; // もし上記の誤った代入が許可された場合、 // constオブジェクト「c」が変更される可能性がある }
Cプログラミング言語では、 const / volatile は第一レベルにのみ追加できることに注意してください:
char** p = 0; char * const* p1 = p; // CとC++の両方で有効 const char* const * p2 = p; // Cではエラー、C++では有効
関数ポインタ変換
void (*p)(); void (**pp)() noexcept = &p; // error: cannot convert to pointer to noexcept function struct S { typedef void (*p)(); operator p(); }; void (*q)() noexcept = S(); // error: cannot convert to pointer to noexcept function |
(C++17以降) |
セーフブール問題
C++11以前、ブーリアンコンテキストで使用可能なクラス(例えば if ( obj ) { ... } )を設計する際には問題があった:ユーザー定義変換関数(例: T :: operator bool ( ) const ; )が与えられた場合、暗黙の変換シーケンスではその関数呼び出し後に追加の標準変換シーケンスが許可される。これは結果の bool が int に変換される可能性があることを意味し、 obj << 1 ; や int i = obj ; のようなコードが許可されてしまう。
この問題に対する初期の解決策の一つは std::basic_ios に見ることができます。これは当初 operator void * を定義していたため、 if ( std:: cin ) { ... } のようなコードは、 void * が bool に変換可能であるためコンパイルされます。しかし int n = std:: cout ; は、 void * が int に変換不可能であるためコンパイルされません。この方法でもなお、 delete std:: cout ; のような無意味なコードがコンパイルされてしまう問題が残っていました。
C++11以前の多くのサードパーティライブラリは、より精巧な解決策である Safe Boolイディオム を採用していました。 std::basic_ios も LWG issue 468 を通じてこのイディオムを許可しており、 operator void * は置き換えられました( 注記 を参照)。
C++11以降、 explicit bool変換 を使用してセーフブール問題を解決することも可能です。
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| CWG 170 | C++98 |
メンバポインタ変換の動作が不明確であった
派生クラスが元のメンバを持たない場合 |
明確化された |
| CWG 172 | C++98 | 列挙型の昇格がその基盤となる型に基づいて行われていた | 代わりにその値の範囲に基づいて行われるように変更 |
|
CWG 330
( N4261 ) |
C++98 |
double
*
const
(
*
p
)
[
3
]
からの変換
double const * const ( * p ) [ 3 ] へが無効であった |
有効に変更 |
| CWG 519 | C++98 |
ヌルポインタ値は他のポインタ型に変換する際に
保持されることが保証されていなかった |
常に保持される |
| CWG 616 | C++98 |
初期化されていないオブジェクトおよび無効な値の
ポインタオブジェクトに対する左辺値から右辺値への 変換の動作は常に未定義であった |
不定値の
unsigned
char
は許可される; 無効なポインタの使用は 実装定義となる |
| CWG 685 | C++98 |
列挙型の基盤型は、固定されている場合でも
整数プロモーションで優先されなかった |
優先される |
| CWG 707 | C++98 |
整数から浮動小数点への変換
はすべての場合で定義された動作を持っていた |
変換される値が
変換先の範囲外である場合 動作は未定義となる |
| CWG 1423 | C++11 | std::nullptr_t は直接初期化とコピー初期化の両方で bool に変換可能であった | 直接初期化のみ |
| CWG 1773 | C++11 |
潜在的に評価される式に現れる名前式において、
オブジェクトがodr-usedされない場合でも、 左辺値から右辺値への変換中に評価される可能性がある |
評価されない |
| CWG 1781 | C++11 |
std::nullptr_t
から
bool
への変換は、直接初期化でのみ有効であるにもかかわらず、
暗黙変換と見なされていた |
暗黙変換とは見なされ
なくなった |
| CWG 1787 | C++98 |
レジスタにキャッシュされた不定値の
unsigned char からの読み取り動作は未定義だった |
明確に定義された動作に変更 |
| CWG 1981 | C++11 | 文脈的変換が明示的変換関数と見なされる | 考慮されない |
| CWG 2140 | C++11 |
lvalueからrvalueへの変換が
std::nullptr_t のlvalueからメモリからこれらのlvalueをフェッチするかどうかが不明確であった |
フェッチされない |
| CWG 2310 | C++98 |
派生クラスから基底クラスへのポインタ変換および
基底クラスから派生クラスへのポインタ-to-member変換において、 派生クラス型が不完全でも可能であった |
完全型でなければならない |
| CWG 2484 | C++20 |
char8_t
と
char16_t
は異なる整数昇格戦略を持っていたが、
両方に対応することが可能である |
char8_t
は
char16_t
と同じ方法で
昇格されるべきである |
| CWG 2485 | C++98 | ビットフィールドを含む整数昇格の仕様が十分に明確ではなかった | 仕様を改善 |
| CWG 2813 | C++23 |
クラスprvalueの明示的
オブジェクトメンバー関数が呼び出される際に一時オブジェクト実体化が発生する |
この場合には発生しない
|
| CWG 2861 | C++98 |
型にアクセスできないオブジェクトへのポインタを
基底クラスのサブオブジェクトへのポインタに変換できた |
この場合の動作は
未定義である |
| CWG 2879 | C++17 |
一時的な実体化変換が、左辺値を期待する演算子のオペランドとして
右辺値に適用された |
一部の場合に適用されない |
| CWG 2899 | C++98 |
左辺値から右辺値への変換が無効な値表現を持つオブジェクトを
指定する左辺値に適用される可能性があった |
この場合の動作は
未定義である |
| CWG 2901 | C++98 | unsigned int 左辺値から左辺値から右辺値への変換結果が int オブジェクトを参照し、値が - 1 の場合、不明確であった | 明確化された |
関連項目
|
C documentation
for
Implicit conversions
|
|
Cドキュメント
の
暗黙の型変換
|