C++
まだ2ポインターではないconst
ポインター(例:T const * const
)を暗黙的または明示的にキャストしたり、何か(関数など)を介して処理したり、そうでなければ変換したりしてT const * const
、初期化に使用することなく、または使用する前にを生成できるかどうかを知りたいとして宣言されている変数T const * const
。これどうやってするの?
T*
から始めれば、1 つconst_cast
(キャストが一度に 1 つしかキャストできない場合は 2 つ) で十分だと思いましたconst
が、明らかにそうではありません。T const * const
コード内の多くの変数は、キャストまたは関数からの戻りによる別の失敗した試みを示しています。すべてのキャストで、末尾にconst
. (const
の左側を*
先頭const
、 の右側を*
末尾と呼びconst
ます。) キャストが失敗したため、const
スルー直接初期化を強制しようとして失敗しました。これは でコンパイルされましたVC11
。stack-crooked.com の g++は、論理的に同等のコンソール出力を提供しますが、名前は異なりますtypeid(/*...*/).name()
.
#include <iostream>
#include <typeinfo>
using namespace std;
int const * const foo()
{
return nullptr;
}
int main()
{
int x = 7;
auto a1 = &x;
cout << typeid(a1).name() << endl;
auto a2 = const_cast<int const *>(&x);
cout << typeid(a2).name() << endl;
auto a3 = const_cast<int * const>(&x);
cout << typeid(a3).name() << endl;
auto a4 = const_cast<int const * const>(&x);
cout << typeid(a4).name() << endl;
auto a5 = const_cast<int const * const>(a4);
cout << typeid(a5).name() << endl;
auto a6 = (int const * const) &x;
cout << typeid(a6).name() << endl;
auto a7 = static_cast<int const * const>(a4);
cout << typeid(a7).name() << endl;
auto a8 = reinterpret_cast<int const * const>(a4);
cout << typeid(a8).name() << endl;
auto a9 = foo();
cout << typeid(a9).name() << endl;
int const * const a10 = &x;
cout << typeid(a10).name() << endl;
cout << ( typeid(a10) == typeid(a4) ) << endl;
auto a12 = a10;
cout << typeid(a12).name() << endl;
cout << ( typeid(a12) == typeid(a4) ) << endl;
}
期待される結果と実際の結果、および質問:
質問番号は、同じ番号のa#
変数に対応しています。
- 期待通りの結果が得られました
int *
- 期待通りの結果が得られました
int const *
- 期待さ
int* const
れていましたが、得られましたint*
。はconst_cast
その末尾のconst
引数を無視しましたか?その理由は? 戻り値は引数と同じ定数と型であるため、キャストは実行されましたか? - 期待さ
int const * const
れていましたが、得られましたint const*
。はconst_cast
その末尾のconst
引数を無視しましたか?その理由は? - 引数の先頭
const_cast<int const * const>
に既に. 予想される。を得た。はその末尾の引数を無視しましたか?その理由は?const
a4
const
int const * const
int const*
const_cast
const
- 予想される
int const * const
。を得int const*
た。明示的なキャストが引き続き末尾を除外するのはなぜconst
ですか? - 予想される
int const * const
。を得int const*
た。static_cast
末尾の を除外するのはなぜconst
ですか? - 予想される
int const * const
。を得int const*
た。reinterpret_cast
末尾の を除外するのはなぜconst
ですか? - 予想される
int const * const
。を得int const*
た。関数の戻り値を初期化しても、結果int const * const
の末尾が除外されるのはなぜですか?const
- 予想される
int const * const
。デバッガーint const*
からではなく、コンソール出力から取得しました。a10
として明示的に宣言されてint const * const
いるのに、なぜtypeid().name()
末尾の const を除外するのでしょうか?operator==
では1
、なぜtypeid()
それ自体 (名前だけでなく) が のa10
それと同等なのa4
ですか? VC11 デバッガーはa10
、 のタイプを としてリストしますint const * const
。typeid()
なぜ と のものと違うのtypeid().name()
ですか? どちらが正しいですか? - 変数名
a11
は「all」に似ているので省略。 - 明示的に宣言された に初期化されているため、そうであると予想
a12
していました。 譲りますので、まだまだです。コンソール出力とデバッガーの両方から取得しました。期待される結果と異なるのはなぜですか?int const * const
a10
int const * const
operator==
1
typeid()
int const*
int const*
すべてのキャスト、関数の戻り値、および初期化は、一度に 1 つのキャストのみに制限さconst
れていますか? const
彼らがキャストできるのはリーディングだけですか?