C++11で、ポインタ変数のもとの型と同じ型の変数を宣言する方法
みなさんお久しぶりです。
最近バイトとか研究とかでない個人的な開発をする余裕がなくなっていて、記事として公開できるネタが少なくてなかなか更新できていません(この状態は今後しばらく続くと思います)。
さて今回の記事は、「ポインタ変数のもとの型と同じ型の変数を宣言する方法」です。
具体的にどういうことかというと、下のようなコードを例に説明します。
int* hoge = new int[10]; // int*型の変数hoge decltype(*hoge) fuga; // fugaの型はこのままだとint&
このように単純に書いてしまうとint&
型の変数が宣言されるが、やっぱりどうしてもint
型の変数を宣言したい!ということです。
つまるところ、「ポインタ型からどうやってもとの型を取ってくるねん」ということになるのですが、天下のGoogleで検索すると、我らが救世主stackoverflowにほぼドンピシャな記事がありました(http://stackoverflow.com/questions/8696452/get-value-type-of-dereferencable-types)。
この記事で書かれているのは、C++のtemplate
構造体を宣言して、その中でtypedef
するみたいな方法です。
この方法で全然問題ないと思うんですが、この方法だと得られるのはあくまでtypedef
された型であって、もとの型ではないので、IntelliSenseで型名を表示すると汚らしい形式になって非常に気持ちが悪いです。
template<typename> struct _dereference; template<typename T> struct _dereference <T*> { typedef T type; }; int* hoge = new int[10]; _dereference<decltype(hoge)>::type fuga; // 実質int型だけどIntelliSenseの表示は // _dereference<int*>::type
なので、このstackoverflowの回答のアイデアをもとに、IntelliSenseにやさしい(?)方法をとります。
typedef
してるのがIntelliSenseが汚らしい表示をする原因なので、typedef
せずにダミーメンバをdecltype
することで解決します。
template<typename> struct _dereference; template<typename T> struct _dereference < T* > { T _dummy; }; #define dereference(T) decltype(_dereference<T>()._dummy) ... int* hoge = new int[10]; dereference(decltype(hoge)) fuga; // 正真正銘int型のfugaになった!
少し一般的に、ポインタ型をdereferenceするためのマクロという形で書いてみました。
コードの実行に使うデータ量は手でfuga
の型名を直打ちするのと全く変わらないです。
生成されるコード量もたぶん変わらないでしょう。
コンパイル時間は知りませんが。
2014/07/06修正
各コードの構造体の名前を変えました。