どうやら、コンパイラはそれらを無関係な型と見なし、したがってreinterpret_cast
必要とされている。なぜこれがルールですか?
これらは完全に異なるタイプであり、標準を参照してください。
3.9.1基本タイプ[basic.fundamental]
1文字charとして宣言されたオブジェクトは、実装の基本文字セットのメンバーを格納するのに十分な大きさでなければなりません。このセットの文字が文字オブジェクトに格納されている場合、その文字オブジェクトの整数値は、その文字の単一文字リテラル形式の値と等しくなります。 charオブジェクトが負の値を保持できるかどうかは実装定義です。文字は明示的に符号なしまたは
署名済み。 プレーン文字、符号付き文字、および符号なし文字は、3つの異なるタイプです。文字、符号付き文字、およびunsigned charは同じ量のストレージを占有し、同じアライメント要件を持ちます(basic.types);つまり、それらは同じオブジェクト表現を持ちます。文字タイプの場合、オブジェクトのすべてのビット
表現は価値表現に参加します。符号なし文字タイプの場合、値表現のすべての可能なビットパターンは数字を表します。これらの要件は、他のタイプには当てはまりません。特定の実装では、プレーンなcharオブジェクトは、signed charまたはunsigned charと同じ値を取ることができます。どちらが実装定義です。
これに類似しているのは、以下が失敗する理由でもあります。
unsigned int* a = new unsigned int(10);
int* b = static_cast<int*>(a); // error different types
a
とb
は完全に異なるタイプです。実際に質問しているのは、なぜstatic_castが以下を問題なく実行できるのか制限している理由です
unsigned int a = new unsigned int(10);
int b = static_cast<int>(a); // OK but may result in loss of precision
そして、なぜターゲットタイプが同じビットフィールド幅であり、表現できると推定できないのですか?ターゲットをソースから派生させ、ダウンキャストを実行する場合を除き、ポインターに対してはスカラー型に対してこれを行うことができますが、ポインター間のキャストは機能しません。
Bjarne Stroustropは、このリンクでstatic_cast
が役立つ理由を述べています: http://www.stroustrup.com/bs_faq2.html#static-cast ですが、省略形ではstatic_cast
は異なるポインタータイプ間のキャストをサポートしていないため、コンパイラーはこのエラーをキャッチして警告を発することができるため、ユーザーは意図を明確に述べ、意図するものが達成できることをコンパイラーに確認する機会を与えますユーザーが本当にこの変換を行いたい場合は、reinterpret_cast
を使用する必要があります。