web-dev-qa-db-ja.com

変数の型を取得するにはどうすればよいですか?

C++では、どのようにして変数の型を見つけるのですか?

90
0x499602D2

typeid演算子 を使用できます。

#include <typeinfo>
...
cout << typeid(variable).name() << endl;
113
Rich O'Kelly

静的アサーションの場合、C++ 11はdecltypeを導入しました。これは特定のシナリオで非常に便利です。

21
user2074102

変数がある場合

int k;

あなたはそのタイプを取得することができます

cout << typeid(k).name() << endl;

SOに関する次のスレッドを参照してください。 類似の質問

11
Amit

通常、C++で変数の型を見つけたいのは間違った質問です。 CやPascalなどの手続き型言語から持ち歩くものである傾向があります。

タイプに応じて異なる動作をコーディングしたい場合は、例えば 関数のオーバーロード および オブジェクトの継承 。これは、C++の最初の日にはすぐには意味がありませんが、そのままにしてください。

9
Pontus Gagge

C++とJavascriptの主な違いは、C++が静的型言語であるのに対し、javascriptは動的であることです。

動的型付き言語では、変数には何でも含めることができ、その型は保持する値によって時々刻々と与えられます。静的型付き言語では、変数の型が宣言されており、変更できません。

動的ディスパッチとオブジェクトの構成とサブタイピング(継承と仮想関数)、静的ディスパッチとスーパータイピング(テンプレートCRTPを使用)が可能ですが、いずれの場合も変数の型はコンパイラーに認識されている必要があります。

あなたがそれが何であるか、あるいは何であるかを知らない立場にいるなら、それはあなたが言語が動的な型システムを持っているので何かを設計したからです。

その場合は、使用している言語にとって自然ではない土地に入るため、デザインを再考するほうが良いでしょう(キャタピラーのある高速道路や車のある水の中を行くようなものです)

7

Sizeof()を使用するのと同じように、typeid()を使用するための有効なユースケースがあると思います。テンプレート関数の場合、最大限の機能と柔軟性を提供するために、テンプレート変数に基づいてコードを特殊なケースにする必要があります。

ポリモーフィズムを使用するよりも、サポートされている各タイプに対して関数のインスタンスを1つ作成する方がはるかにコンパクトで保守可能です。その場合でも、私はこのトリックを使用して、関数の本体を1回だけ記述することができます。

コードはテンプレートを使用するため、以下のswitchステートメントは静的に1つのコードブロックのみに解決し、すべての誤ったケースAFAIKを最適化することに注意してください。

Tが1つのタイプと別のタイプである場合に変換を処理する必要がある場合があるこの例を考えてみましょう。ハードウェアがmyClassAまたはmyClassBタイプのいずれかを使用するハードウェアにアクセスするために、クラスの特殊化に使用します。不一致では、データの変換に時間を費やす必要があります。

switch ((typeid(T)) {
  case typeid(myClassA):
    // handle that case
    break;
  case typeid(myClassB):
    // handle that case
    break;
  case typeid(uint32_t):
    // handle that case
    break;
  default:
    // handle that case
}
5
Dan Truong

私の答えが役立つかどうかはわかりません。

簡単な答えは、それを使用するために変数の型を実際に知る必要はありません。

静的変数に型を指定する必要がある場合は、単にautoを使用できます。

クラスまたは構造体で「auto」を使用するより洗練されたケースでは、decltypeでテンプレートを使用することをお勧めします。

たとえば、他の人のライブラリを使用していて、「unknown_var」という変数があり、それをベクトルまたは構造体に入れたい場合、完全にこれを行うことができます。

template <typename T>
struct my_struct {
    int some_field;
    T my_data;
};
vector<decltype(unknown_var)> complex_vector;
vector<my_struct<decltype(unknown_var)> > simple_vector

お役に立てれば。

編集:良い測定のために、ここに私が考えることができる最も複雑なケースがあります:未知のタイプのグローバル変数を持つこと。この場合、c ++ 14とテンプレート変数が必要になります。

このようなもの:

template<typename T> vector<T> global_var;

void random_func (auto unknown_var) {
    global_var<decltype(unknown_var)>.Push_back(unknown_var);
}

それはまだ少し退屈ですが、タイプレス言語に到達するのと同じくらい近いです。テンプレート変数を参照するときは常に、必ずテンプレート仕様をそこに置いてください。

3
gohongyi
#include <typeinfo>

...
string s = typeid(YourClass).name()
2
rad