標準変換Standard conversions

C++ 言語では、基本型間での変換が定義されています。The C++ language defines conversions between its fundamental types. また、ポインター、参照、およびメンバーへのポインターの派生型についても変換が定義されています。It also defines conversions for pointer, reference, and pointer-to-member derived types. これらの変換は、標準変換と呼ばれます。These conversions are called standard conversions.

このセクションでは、次の標準変換について説明します。This section discusses the following standard conversions:

  • 整数の上位変換Integral promotions

  • 整数の変換Integral conversions

  • 浮動小数点の変換Floating conversions

  • 浮動小数点と整数の変換Floating and integral conversions

  • 算術変換Arithmetic conversions

  • ポインター変換Pointer conversions

  • 参照変換Reference conversions

  • メンバーへのポインター変換Pointer-to-member conversions

    注意

    ユーザー定義型では独自の変換を指定できます。User-defined types can specify their own conversions. ユーザー定義型の変換については、「コンストラクター変換」で説明されています。Conversion of user-defined types is covered in Constructors and Conversions.

次のコードは、変換 (この例では整数の上位変換) の実行例を示しています。The following code causes conversions (in this example, integral promotions):

long  long_num1, long_num2;
int   int_num;

// int_num promoted to type long prior to assignment.
long_num1 = int_num;

// int_num promoted to type long prior to multiplication.
long_num2 = int_num * long_num2;

参照型を生成する場合のみ、変換の結果が左辺値になります。The result of a conversion is an l-value only if it produces a reference type. たとえば、として宣言されたユーザー定義の変換は operator int&() 参照を返し、は左辺値です。For example, a user-defined conversion declared as operator int&() returns a reference and is an l-value. ただし、として宣言された変換は operator int() オブジェクトを返し、左辺値ではありません。However, a conversion declared as operator int() returns an object and isn't an l-value.

整数の上位変換Integral promotions

整数型のオブジェクトは、より大きな整数型、つまり、より大きな値のセットを表すことができる型に変換できます。Objects of an integral type can be converted to another wider integral type, that is, a type that can represent a larger set of values. この拡大型の変換は、整数の上位変換と呼ばれます。This widening type of conversion is called integral promotion. 整数の上位変換では、別の整数型を使用できる場所であれば、式で次の型を使用できます。With integral promotion, you can use the following types in an expression wherever another integral type can be used:

  • 型および型のオブジェクト、リテラル、および定数 char****short intObjects, literals, and constants of type char and short int

  • 列挙型Enumeration types

  • int ビットフィールドint bit fields

  • 列挙子Enumerators

C++ の昇格は、昇格後の値が上位変換前の値と同じであることが保証されるため、"値を保持する" となります。C++ promotions are "value-preserving," as the value after the promotion is guaranteed to be the same as the value before the promotion. 値を保持する昇格では、 char int int が元の型の全範囲を表すことができる場合は、短い整数型 (ビットフィールドや型のオブジェクトなど) のオブジェクトが型に昇格されます。In value-preserving promotions, objects of shorter integral types (such as bit fields or objects of type char) are promoted to type int if int can represent the full range of the original type. int 値の全範囲を表すことができない場合、オブジェクトは型に昇格され unsigned int ます。If int can't represent the full range of values, then the object is promoted to type unsigned int. この方法は、標準 C で使用される方法と同じですが、値を維持する変換では、オブジェクトの "有無" が保持されません。Although this strategy is the same as the one used by Standard C, value-preserving conversions don't preserve the "signedness" of the object.

値保持の上位変換および符号の有無を保持する上位変換は、通常、同じ結果を生成します。Value-preserving promotions and promotions that preserve signedness normally produce the same results. ただし、昇格したオブジェクトが次のように表示されると、異なる結果が生成される可能性があります。However, they can produce different results if the promoted object appears as:

  • 、、、、、、、 / % /= %= < <= > またはのオペランド>=An operand of /, %, /=, %=, <, <=, >, or >=

    これらの演算子は、結果を判断するために符号に依存します。These operators rely on sign for determining the result. このようなオペランドに適用した場合、値を維持し、符号を維持する昇格によって異なる結果が生成されます。Value-preserving and sign-preserving promotions produce different results when applied to these operands.

  • またはの左オペランド。 >>``>>=The left operand of >> or >>=

    これらの演算子は、シフト演算で符号付きと符号なしの数量を別々に扱います。These operators treat signed and unsigned quantities differently in a shift operation. 符号付きの数量の場合、右シフト演算では符号ビットが空いているビット位置に伝達されますが、空いたビット位置は符号なしの数量でゼロで埋められます。For signed quantities, a right shift operation propagates the sign bit into the vacated bit positions, while the vacated bit positions are zero-filled in unsigned quantities.

  • オーバーロードされた関数の引数、またはオーバーロードされた演算子のオペランド。引数の一致のオペランド型の有無に依存します。An argument to an overloaded function, or the operand of an overloaded operator, that depends on the signedness of the operand type for argument matching. オーバーロードされた演算子の定義の詳細については、「オーバーロードされた演算子」を参照してください。For more information about defining overloaded operators, see Overloaded operators.

整数の変換Integral conversions

整数変換は、整数型の間の変換です。Integral conversions are conversions between integral types. 整数型は char 、、 short (または short int )、、 int long 、および long long です。The integral types are char, short (or short int), int, long, and long long. これらの型は、またはで修飾することができ、 signed unsigned unsigned の短縮形として使用でき unsigned int ます。These types may be qualified with signed or unsigned, and unsigned can be used as shorthand for unsigned int.

signed から unsigned へSigned to unsigned

符号付き整数型のオブジェクトは、対応する符号なし型に変換できます。Objects of signed integral types can be converted to corresponding unsigned types. これらの変換が発生した場合、実際のビットパターンは変わりません。When these conversions occur, the actual bit pattern doesn't change. ただし、データの解釈は変わります。However, the interpretation of the data changes. 次のコードを考えてみます。Consider this code:

#include <iostream>

using namespace std;
int main()
{
    short  i = -3;
    unsigned short u;

    cout << (u = i) << "\n";
}
// Output: 65533

前の例では、 signed short i が定義され、負の数に初期化されています。In the preceding example, a signed short, i, is defined and initialized to a negative number. 式は、が (u = i) i に代入される前に、をに変換し unsigned short u ます。The expression (u = i) causes i to be converted to an unsigned short before the assignment to u.

unsigned から signed へUnsigned to signed

符号なし整数型のオブジェクトは、対応する符号付き型に変換できます。Objects of unsigned integral types can be converted to corresponding signed types. ただし、符号なしの値が符号付きの型の表現可能な範囲外の場合、次の例に示すように、結果に正しい値が設定されません。However, if the unsigned value is outside the representable range of the signed type, the result won't have the correct value, as demonstrated in the following example:

#include <iostream>

using namespace std;
int main()
{
short  i;
unsigned short u = 65533;

cout << (i = u) << "\n";
}
//Output: -3

前の例で u は、は、式を unsigned short 評価するために符号付きの数量に変換する必要がある整数のオブジェクトです (i = u)In the preceding example, u is an unsigned short integral object that must be converted to a signed quantity to evaluate the expression (i = u). では、値が正しく表現できないため、 signed short データが誤って解釈されます。Because its value can't be properly represented in a signed short, the data is misinterpreted as shown.

浮動小数点の変換Floating point conversions

浮動小数点型のオブジェクトは、より精度の高い浮動小数点型に安全に変換できます。つまり、変換で精度は低下しません。An object of a floating type can be safely converted to a more precise floating type — that is, the conversion causes no loss of significance. たとえば、からへの float 変換 double またはからへの変換 double long double は安全であり、値は変更されません。For example, conversions from float to double or from double to long double are safe, and the value is unchanged.

また、浮動小数点型のオブジェクトは、その型で表現できる範囲内にある場合は、より精度の低い型に変換することもできます。An object of a floating type can also be converted to a less precise type, if it's in a range representable by that type. (浮動小数点型の範囲については、「浮動小数点値の制限」を参照してください)。元の値が正確に表現できない場合は、次に大きい値または次に小さい表現可能値のいずれかに変換できます。(See Floating Limits for the ranges of floating types.) If the original value isn't representable precisely, it can be converted to either the next higher or the next lower representable value. そのような値が存在しない場合、結果は未定義になります。The result is undefined if no such value exists. 次の例を確認してください。Consider the following example:

cout << (float)1E300 << endl;

型で表現可能な最大値 float は 3.402823466 e38 です。これは1E300 よりもはるかに小さい数値です。The maximum value representable by type float is 3.402823466E38 — a much smaller number than 1E300. そのため、数値は無限大に変換され、結果は "inf" になります。Therefore, the number is converted to infinity, and the result is "inf".

整数型と浮動小数点型の変換Conversions between integral and floating point types

特定の式は、浮動小数点型のオブジェクトから整数型のオブジェクトへの変換、またはその逆の変換が発生する場合があります。Certain expressions can cause objects of floating type to be converted to integral types, or vice versa. 整数型のオブジェクトが浮動小数点型に変換され、元の値が正確に表現できない場合、結果は次の上位または次に表現可能な値のいずれかになります。When an object of integral type is converted to a floating type, and the original value isn't representable exactly, the result is either the next higher or the next lower representable value.

浮動小数点型のオブジェクトを整数型に変換すると、小数部分が切り捨てられるか、ゼロに丸められます。When an object of floating type is converted to an integral type, the fractional part is truncated, or rounded toward zero. 1.3 のような数値が1に変換され、-1.3 が-1 に変換されます。A number like 1.3 is converted to 1, and -1.3 is converted to -1. 切り捨てられた値が表現可能な最大値より大きい場合、または表現可能な最小値より小さい場合、結果は未定義になります。If the truncated value is higher than the highest representable value, or lower than the lowest representable value, the result is undefined.

算術変換Arithmetic conversions

多くの二項演算子 (「二項演算子を使用した式」で説明されています) は、オペランドの変換を実行し、同じように結果を生成します。Many binary operators (discussed in Expressions with binary operators) cause conversions of operands, and yield results the same way. これらの演算子の原因となる変換は、通常の算術変換と呼ばれます。The conversions these operators cause are called usual arithmetic conversions. 次の表に示すように、ネイティブ型が異なるオペランドの算術変換が実行されます。Arithmetic conversions of operands that have different native types are done as shown in the following table. typedef 型は、基になるネイティブ型に従って動作します。Typedef types behave according to their underlying native types.

型変換の条件Conditions for type conversion

満たされる条件Conditions Met 変換Conversion
どちらかのオペランドが型 long double です。Either operand is of type long double. その他のオペランドは型に変換され long double ます。Other operand is converted to type long double.
前の条件が満たされておらず、いずれかのオペランドが型 double です。Preceding condition not met and either operand is of type double. その他のオペランドは型に変換され double ます。Other operand is converted to type double.
前の条件が満たされておらず、いずれかのオペランドが型 float です。Preceding conditions not met and either operand is of type float. その他のオペランドは型に変換され float ます。Other operand is converted to type float.
上の条件が満たされていない (どちらのオペランドも浮動小数点型ではない)Preceding conditions not met (none of the operands are of floating types). オペランドは、次のように整数の上位変換を取得します。Operands get integral promotions as follows:

-どちらかのオペランドが型の場合 unsigned long 、もう一方のオペランドは型に変換され unsigned long ます。- If either operand is of type unsigned long, the other operand is converted to type unsigned long.
-前の条件が満たされず、どちらかのオペランドが型で、もう一方が型である場合 long unsigned int 、両方のオペランドが型に変換され unsigned long ます。- If preceding condition not met, and if either operand is of type long and the other of type unsigned int, both operands are converted to type unsigned long.
-前の2つの条件が満たされず、どちらかのオペランドが型の場合 long 、もう一方のオペランドは型に変換され long ます。- If the preceding two conditions aren't met, and if either operand is of type long, the other operand is converted to type long.
-前の3つの条件が満たされず、どちらかのオペランドが型の場合 unsigned int 、もう一方のオペランドは型に変換され unsigned int ます。- If the preceding three conditions aren't met, and if either operand is of type unsigned int, the other operand is converted to type unsigned int.
-上記のいずれの条件も満たされない場合、両方のオペランドが型に変換され int ます。- If none of the preceding conditions are met, both operands are converted to type int.

次のコードは、表で説明している変換規則を示しています。The following code illustrates the conversion rules described in the table:

double dVal;
float fVal;
int iVal;
unsigned long ulVal;

int main() {
   // iVal converted to unsigned long
   // result of multiplication converted to double
   dVal = iVal * ulVal;

   // ulVal converted to float
   // result of addition converted to double
   dVal = ulVal + fVal;
}

上記の例の最初のステートメントは、2 つの整数型、iValulVal の乗算を示しています。The first statement in the preceding example shows multiplication of two integral types, iVal and ulVal. 満たされている条件は、どちらのオペランドも浮動小数点型ではないことと、1つのオペランドが型であることです unsigned intThe condition met is that neither operand is of floating type, and one operand is of type unsigned int. そのため、もう一方のオペランドは iVal 型に変換され unsigned int ます。So, the other operand, iVal, is converted to type unsigned int. 結果はに割り当てられ dVal ます。The result is then assigned to dVal. ここで条件を満たすのは、1つのオペランドが型 double であるため、 unsigned int 乗算の結果が型に変換されるためです doubleThe condition met here is that one operand is of type double, so the unsigned int result of the multiplication is converted to type double.

前の例の2番目のステートメントは、との整数型の加算を示して float fVal ulVal います。The second statement in the preceding example shows addition of a float and an integral type: fVal and ulVal. ulVal変数は、型 float (テーブルの3番目の条件) に変換されます。The ulVal variable is converted to type float (third condition in the table). 加算の結果は、型 double (テーブルの2番目の条件) に変換され、に割り当てられ dVal ます。The result of the addition is converted to type double (second condition in the table) and assigned to dVal.

ポインター変換Pointer conversions

ポインターは、代入、初期化、比較、および他の式の中で変換できます。Pointers can be converted during assignment, initialization, comparison, and other expressions.

クラスへのポインターPointer to classes

クラスへのポインターを基底クラスへのポインターに変換できる 2 つのケースがあります。There are two cases in which a pointer to a class can be converted to a pointer to a base class.

最初のケースは、指定した基底クラスがアクセス可能であり、変換が明確である場合です。The first case is when the specified base class is accessible and the conversion is unambiguous. あいまいな基底クラス参照の詳細については、「複数の基底クラス」を参照してください。For more information about ambiguous base-class references, see Multiple base classes.

基底クラスにアクセスできるかどうかは、派生で使用される継承の種類によって決まります。Whether a base class is accessible depends on the kind of inheritance used in derivation. 次の図に示す継承を考えます。Consider the inheritance illustrated in the following figure.

基本-クラスのアクセシビリティを示す継承グラフInheritance graph showing base-class accessibility
基底クラスのアクセシビリティを示す継承グラフInheritance Graph for Illustration of Base-Class Accessibility

次の表は、図で示す状況に対する基底クラスのアクセシビリティを示します。The following table shows the base-class accessibility for the situation illustrated in the figure.

関数の型Type of Function 派生Derivation 変換 (Conversion from

B * を * 法的にB* to A* Legal?
外部 (非クラス スコープ) 関数External (not class-scoped) function プライベートPrivate いいえNo
ProtectedProtected いいえNo
パブリックPublic はいYes
B のメンバー関数 (B のスコープ内)B member function (in B scope) プライベートPrivate はいYes
ProtectedProtected はいYes
パブリックPublic はいYes
C のメンバー関数 (C のスコープ内)C member function (in C scope) プライベートPrivate いいえNo
ProtectedProtected はいYes
パブリックPublic はいYes

クラスへのポインターを基底クラスへのポインターに変換できる 2 番目のケースは、明示的な型変換を使用する場合です The second case in which a pointer to a class can be converted to a pointer to a base class is when you use an explicit type conversion. 明示的な型変換の詳細については、「明示的な型変換演算子」を参照してください。For more information about explicit type conversions, see Explicit type conversion operator.

このような変換の結果として、基底クラスによって完全に記述されているオブジェクトの部分であるサブオブジェクトへのポインターが返されます。The result of such a conversion is a pointer to the subobject, the portion of the object that is completely described by the base class.

次のコードでは、2 つのクラス AB を定義しています。BA から派生しています。The following code defines two classes, A and B, where B is derived from A. (継承の詳細については、「派生クラス」を参照してください)。次に bObject 、、型のオブジェクト、および B pA オブジェクトを指す2つのポインター (と) を定義し pB ます。(For more information on inheritance, see Derived Classes.) It then defines bObject, an object of type B, and two pointers (pA and pB) that point to the object.

// C2039 expected
class A
{
public:
    int AComponent;
    int AMemberFunc();
};

class B : public A
{
public:
    int BComponent;
    int BMemberFunc();
};
int main()
{
   B bObject;
   A *pA = &bObject;
   B *pB = &bObject;

   pA->AMemberFunc();   // OK in class A
   pB->AMemberFunc();   // OK: inherited from class A
   pA->BMemberFunc();   // Error: not in class A
}

ポインター pA は、型 A * へのポインターを意味するものとして解釈できる型 A です。The pointer pA is of type A *, which can be interpreted as meaning "pointer to an object of type A." のメンバー bObject (やなど BComponent BMemberFunc ) は型に固有であるため、を使用してアクセスすることはできませ B pA ん。Members of bObject (such as BComponent and BMemberFunc) are unique to type B and are therefore inaccessible through pA. pA ポインターは、クラス A で定義されているオブジェクトのこれらの特性 (メンバー関数とデータ) にのみアクセスを許可します。The pA pointer allows access only to those characteristics (member functions and data) of the object that are defined in class A.

関数へのポインターPointer to function

void *void * がそのポインターを保持するのに十分な大きさであれば、関数へのポインターを型に変換できます。A pointer to a function can be converted to type void *, if type void * is large enough to hold that pointer.

void へのポインターPointer to void

型へのポインターは void 、他の型へのポインターに変換できますが、明示的な型キャスト (C の場合とは異なります) を使用した場合のみです。Pointers to type void can be converted to pointers to any other type, but only with an explicit type cast (unlike in C). 任意の型へのポインターは、暗黙的に型へのポインターに変換でき void ます。A pointer to any type can be converted implicitly to a pointer to type void. 型の不完全なオブジェクトへのポインターは、(暗黙的に) へのポインターに変換でき void ます。A pointer to an incomplete object of a type can be converted to a pointer to void (implicitly) and back (explicitly). このような変換の結果は、元のポインターの値と同じです。The result of such a conversion is equal to the value of the original pointer. オブジェクトは宣言されている場合は不完全と見なされますが、サイズまたは基本クラスを決定するのに十分な情報がありません。An object is considered incomplete if it's declared, but there's insufficient information available to determine its size or base class.

const volatile 型のポインターに暗黙的に変換できない、または暗黙的に変換できるオブジェクトへのポインター void *A pointer to any object that is not const or volatile can be implicitly converted to a pointer of type void *.

const ポインターと volatile ポインターconst and volatile pointers

C++ では、 const 型または型から volatile 以外の型への標準変換が指定されていません const volatileC++ doesn't supply a standard conversion from a const or volatile type to a type that's not const or volatile. ただし、どの種類の変換も、明示的な型キャストを使用して指定できます (安全でない変換も含む)。However, any sort of conversion can be specified using explicit type casts (including conversions that are unsafe).

注意

静的メンバーへのポインターを除く、メンバーへの C++ ポインターは、通常のポインターとは異なり、標準変換は同じではありません。C++ pointers to members, except pointers to static members, are different from normal pointers and don't have the same standard conversions. 静的メンバーへのポインターは通常のポインターであり、通常のポインターと同じ変換を持ちます。Pointers to static members are normal pointers and have the same conversions as normal pointers.

null ポインターの変換null pointer conversions

0に評価される整数定数式、またはポインター型にキャストされる式は、 null ポインターと呼ばれるポインターに変換されます。An integral constant expression that evaluates to zero, or such an expression cast to a pointer type, is converted to a pointer called the null pointer. このポインターは、常に、任意の有効なオブジェクトまたは関数へのポインターと等しくないことを比較します。This pointer always compares unequal to a pointer to any valid object or function. 例外とは、ベースのオブジェクトへのポインターであり、同じオフセットを持つことができ、別のオブジェクトを指す場合もあります。An exception is pointers to based objects, which can have the same offset and still point to different objects.

C++ 11 では、 nullptr型が C スタイルの null ポインターに優先される必要があります。In C++11, the nullptr type should be preferred to the C-style null pointer.

ポインター式の変換Pointer expression conversions

配列型の式は、同じ型のポインターに変換できます。Any expression with an array type can be converted to a pointer of the same type. 変換の結果は最初の配列要素へのポインターです。The result of the conversion is a pointer to the first array element. 次のコードは、この変換を示す例です。The following example demonstrates such a conversion:

char szPath[_MAX_PATH]; // Array of type char.
char *pszPath = szPath; // Equals &szPath[0].

特定の型を返す関数となる式は、次の場合を除き、その型を返す関数へのポインターに変換されます。An expression that results in a function returning a particular type is converted to a pointer to a function returning that type, except when:

  • 式は、アドレス演算子 () のオペランドとして使用され & ます。The expression is used as an operand to the address-of operator (&).

  • 式が関数呼び出し演算子のオペランドとして使用されています。The expression is used as an operand to the function-call operator.

参照変換Reference conversions

このような場合は、クラスへの参照を基底クラスへの参照に変換できます。A reference to a class can be converted to a reference to a base class in these cases:

  • 指定された基底クラスにアクセスできます。The specified base class is accessible.

  • 変換は明確です。The conversion is unambiguous. (あいまいな基底クラス参照の詳細については、「複数の基底クラス」を参照してください)。(For more information about ambiguous base-class references, see Multiple base classes.)

変換の結果は、基底クラスを表すサブオブジェクトへのポインターです。The result of the conversion is a pointer to the subobject that represents the base class.

メンバーへのポインターPointer to member

クラス メンバーへのポインターは、代入、初期化、比較、および他の式の中で変換できます。Pointers to class members can be converted during assignment, initialization, comparison, and other expressions. このセクションでは、以下のポインターからメンバーへの変換について説明します。This section describes the following pointer-to-member conversions:

基底クラスのメンバーへのポインターPointer to base class member

基底クラスのメンバーへのポインターは、次の条件を満たす場合に、そのクラスから派生したクラスのメンバーへのポインターに変換できます。A pointer to a member of a base class can be converted to a pointer to a member of a class derived from it, when the following conditions are met:

  • 派生クラスへのポインターから基底クラスへのポインターへの逆変換がアクセス可能である。The inverse conversion, from pointer to derived class to base-class pointer, is accessible.

  • 派生クラスが基底クラスからの仮想的な継承でない。The derived class does not inherit virtually from the base class.

左のオペランドがメンバーへのポインターである場合、右のオペランドはメンバーへのポインター型であるか、0 に評価される定数式である必要があります。When the left operand is a pointer to member, the right operand must be of pointer-to-member type or be a constant expression that evaluates to 0. この代入は、次の場合にのみ有効です。This assignment is valid only in the following cases:

  • 右のオペランドが、左のオペランドと同じクラスのメンバーへのポインターである。The right operand is a pointer to a member of the same class as the left operand.

  • 左のオペランドが、右のオペランドのクラスからパブリックかつ明確に派生したクラスのメンバーへのポインターである。The left operand is a pointer to a member of a class derived publicly and unambiguously from the class of the right operand.

メンバー変換への null ポインターnull pointer to member conversions

0に評価される整数定数式は、null ポインターに変換されます。An integral constant expression that evaluates to zero is converted to a null pointer. このポインターは、常に、任意の有効なオブジェクトまたは関数へのポインターと等しくないことを比較します。This pointer always compares unequal to a pointer to any valid object or function. 例外とは、ベースのオブジェクトへのポインターであり、同じオフセットを持つことができ、別のオブジェクトを指す場合もあります。An exception is pointers to based objects, which can have the same offset and still point to different objects.

次のコードは、クラス i のメンバー A へのポインターの定義を示しています。The following code illustrates the definition of a pointer to member i in class A. ポインター pai が 0、つまり null ポインターに初期化されます。The pointer, pai, is initialized to 0, which is the null pointer.

class A
{
public:
int i;
};

int A::*pai = 0;

int main()
{
}

関連項目See also

C++ 言語リファレンスC++ language reference