名前空間
変種
操作

typeid演算子

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 

型の情報を照会します。

ポリモーフィックオブジェクト動的型が既知である必要があり、静的型識別に使用されます。

目次

[編集] 構文

typeid ( ) (1)
typeid ( ) (2)

typeid式は、静的記憶域期間を持ち、std::type_infoまたはそれから派生した型をconst修飾したバージョンのオブジェクトを参照する左辺値式です。

typeidを使用する際に、std::type_infoの標準ライブラリ定義が見えない場合、プログラムは不正です。

[編集] 説明

またはの型がクラス型またはクラス型への参照である場合、そのクラス型は不完全型であってはなりません。

1) を表すstd::type_infoオブジェクトを参照します。が参照型の場合、結果は参照される型のcv非修飾バージョンを表すstd::type_infoオブジェクトを参照します。
2) を検査します。
  • それ以外の場合、typeid式を評価せず、識別するstd::type_infoオブジェクトは式の静的型を表します。左辺値から右辺値への変換、配列からポインタへの変換、または関数からポインタへの変換は実行されません。
  • ただし、prvalue引数に対しては一時オブジェクトの具現化が(形式的に)実行されます。typeid式が出現するコンテキストで引数は破棄可能である必要があります。
(C++17以降)

またはの型がcv修飾されている場合、typeidの結果はcv非修飾型を表すstd::type_infoオブジェクトを参照します(つまり、typeid(const T) == typeid(T))。

オブジェクトが構築中または破棄中(デストラクタ内、またはコンストラクタ内(コンストラクタの初期化リストまたはデフォルトメンバ初期化子を含む))にtypeidが使用された場合、このtypeidによって参照されるstd::type_infoオブジェクトは、それが最も派生したクラスでなくても、構築中または破棄中のクラスを表します。

  1. 他のコンテキストでは、そのようなの評価は未定義動作になります。

[編集] 備考

ポリモーフィック型の式に適用された場合、typeid式の評価にはランタイムオーバーヘッド(仮想テーブルの検索)を伴う場合があります。それ以外の場合、typeid式はコンパイル時に解決されます。

typeidによって参照されるオブジェクトのデストラクタがプログラムの終了時に実行されるかどうかは未指定です。

同じ型に対するtypeid式のすべての評価が同じstd::type_infoオブジェクトを参照する保証はありませんが、それらは等しく比較され、それらのtype_infoオブジェクトのstd::type_info::hash_codeは同一になり、std::type_indexも同様です。

const std::type_info& ti1 = typeid(A);
const std::type_info& ti2 = typeid(A);
 
assert(&ti1 == &ti2); // not guaranteed
assert(ti1 == ti2); // guaranteed
assert(ti1.hash_code() == ti2.hash_code()); // guaranteed
assert(std::type_index(ti1) == std::type_index(ti2)); // guaranteed

[編集] キーワード

typeid

[編集]

type_info::nameが完全な型名を返す実装の1つを使用した出力例。gccなどを使用する場合はc++filt -tでフィルタリングしてください。

#include <iostream>
#include <string>
#include <typeinfo>
 
struct Base {}; // non-polymorphic
struct Derived : Base {};
 
struct Base2 { virtual void foo() {} }; // polymorphic
struct Derived2 : Base2 {};
 
int main()
{
    int myint = 50;
    std::string mystr = "string";
    double *mydoubleptr = nullptr;
 
    std::cout << "myint has type: " << typeid(myint).name() << '\n'
              << "mystr has type: " << typeid(mystr).name() << '\n'
              << "mydoubleptr has type: " << typeid(mydoubleptr).name() << '\n';
 
    // std::cout << myint is a glvalue expression of polymorphic type; it is evaluated
    const std::type_info& r1 = typeid(std::cout << myint); // side-effect: prints 50
    std::cout << '\n' << "std::cout<<myint has type : " << r1.name() << '\n';
 
    // std::printf() is not a glvalue expression of polymorphic type; NOT evaluated
    const std::type_info& r2 = typeid(std::printf("%d\n", myint));
    std::cout << "printf(\"%d\\n\",myint) has type : " << r2.name() << '\n';
 
    // Non-polymorphic lvalue is a static type
    Derived d1;
    Base& b1 = d1;
    std::cout << "reference to non-polymorphic base: " << typeid(b1).name() << '\n';
 
    Derived2 d2;
    Base2& b2 = d2;
    std::cout << "reference to polymorphic base: " << typeid(b2).name() << '\n';
 
    try
    {
        // dereferencing a null pointer: okay for a non-polymorphic expression
        std::cout << "mydoubleptr points to " << typeid(*mydoubleptr).name() << '\n'; 
        // dereferencing a null pointer: not okay for a polymorphic lvalue
        Derived2* bad_ptr = nullptr;
        std::cout << "bad_ptr points to... ";
        std::cout << typeid(*bad_ptr).name() << '\n';
    }
    catch (const std::bad_typeid& e)
    {
        std::cout << " caught " << e.what() << '\n';
    }
}

実行結果の例

======== output from Clang ========
myint has type: i
mystr has type: NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE
mydoubleptr has type: Pd
50
std::cout<<myint has type : NSt3__113basic_ostreamIcNS_11char_traitsIcEEEE
printf("%d\n",myint) has type : i
reference to non-polymorphic base: 4Base
reference to polymorphic base: 8Derived2
mydoubleptr points to d
bad_ptr points to...  caught std::bad_typeid
 
======== output from MSVC ========
myint has type: int
mystr has type: class std::basic_string<char,struct std::char_traits<char>,⮠
class std::allocator<char> >
mydoubleptr has type: double * __ptr64
50
std::cout<<myint has type : class std::basic_ostream<char,struct std::char_traits<char> >
printf("%d\n",myint) has type : int
reference to non-polymorphic base: struct Base
reference to polymorphic base: struct Derived2
mydoubleptr points to double
bad_ptr points to...  caught Attempted a typeid of nullptr pointer!

[編集] 欠陥報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
CWG 492 C++98 typeidがcv修飾された参照に適用された場合
型の場合、結果は参照された型を表します
結果は
cv非修飾参照型を表します
CWG 1416 C++98 トップレベルに関する記述
cv修飾は誤解される可能性があります
記述を改善しました
CWG 1431 C++98 typeidstd::bad_typeidをスローすることのみが許可されていました スローすることが許可されています
一致する派生クラス
CWG 1954 C++98 ヌルポインタのデリファレンスが不明でした
のサブ式でチェックできます
トップレベルでのみチェックされます

[編集] 関連項目

ある型の情報を保持し、typeid演算子によって返されるクラス
(クラス) [編集]
English 日本語 中文(简体) 中文(繁體)