LoginSignup
4
4

More than 5 years have passed since last update.

C++でintなtype_indexを生成する

Last updated at Posted at 2015-12-01

std::type_indexでは何が問題か

大量の型を管理するには遅そうです。

#include <typeindex>
#include <map>
#include <iostream>

int main(){
    // 型をシーケンシャルなidに変換したい.
    std::map<std::type_index, int> type_index_map;
    int next_index = 0;

    // 生成に累計で O(log(n) * n) 時間が掛かる.
    type_index_map[typeid(int)] = next_index++;
    type_index_map[typeid(void)] = next_index++;
    type_index_map[typeid(const char*)] = next_index++;

    // 照合で O(log(n)) 時間掛かる.
    std::cout << "int         mapped -> " << type_index_map[typeid(int)] << std::endl;
    std::cout << "void        mapped -> " << type_index_map[typeid(void)] << std::endl;
    std::cout << "const char* mapped -> " << type_index_map[typeid(const char*)] << std::endl;

    return 0;
}
int         mapped -> 0
void        mapped -> 1
const char* mapped -> 2

template関数で静的なint型変数をラップする

コストがインクリメントとコンパイル時に型ごとに生成される関数コールのみになりなりました。

#include <typeindex>
#include <map>
#include <iostream>

int create_next_id(){
    static int i = 0;
    return i++;
}

template<class T>
int id(){
    static int i = create_next_id();
    return i;
}

int main(){
    // 型をシーケンシャルなidに変換したい.
    std::cout << "int         mapped -> " << id<int>() << std::endl;
    std::cout << "void        mapped -> " << id<void>() << std::endl;
    std::cout << "const char* mapped -> " << id<const char*>() << std::endl;
    std::cout << "int         mapped -> " << id<int>() << std::endl;

    return 0;
}
int         mapped -> 0
void        mapped -> 1
const char* mapped -> 2
int         mapped -> 0

注意するべき点

  • create_next_id()内のstatic変数を外に出すときに翻訳単位に注意する。
  • id<T>()の最初の呼び出し順序によって実行ごとのint値の一意性がないため、実行時に依存しない初期化を必ず伴わせる。
  • templateなクラス内でcreate_next_id(), id<T>()を持つ事によりクラスごとで照合結果の一意性が損なわれる。
  • ただし意図的に分離して相違なクラス間で比較結果を不正なものにしたい場合はメリットになる。
  • 定数時間にこだわる場合は関数コールのコストがinline化されているかどうかに注意すること。
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4