[解決済み] C++ テンプレート内の型名取得
質問
私はテキスト データファイルを解析するためのテンプレート クラスを書いていますが、解析エラーの大部分はデータ ファイル内のエラーに起因すると思われます。
example.txt の解析に失敗しました。MySectiom]キーの値 ("notaninteger") は有効な int ではありません。
テンプレート関数に渡された引数とクラスのメンバ変数から、ファイル名、セクション名、およびキー名を調べることができますが、テンプレート関数が変換しようとしている型の名前を取得する方法がよくわかりません。
私の現在のコードは、単なる文字列やそのようなもののために特別化された、次のようになります。
template<typename T> T GetValue(const std::wstring §ion, const std::wstring &key)
{
std::map<std::wstring, std::wstring>::iterator it = map[section].find(key);
if(it == map[section].end())
throw ItemDoesNotExist(file, section, key)
else
{
try{return boost::lexical_cast<T>(it->second);}
//needs to get the name from T somehow
catch(...)throw ParseError(file, section, key, it->second, TypeName(T));
}
}
データファイルが使用する可能性のあるすべての型について、特定のオーバーロードを作成する必要はないでしょう。
すなわち、このコードは何度も呼び出され、ロード時間はすでにいくらか長くなっているので、完全にコンパイル時のソリューションが私が望むものです。
EDIT: OK これは私が考え出した解決策です。
私は以下の内容を含むtypes.hを持っています。
#pragma once
template<typename T> const wchar_t *GetTypeName();
#define DEFINE_TYPE_NAME(type, name) \
template<>const wchar_t *GetTypeName<type>(){return name;}
それから、DEFINE_TYPE_NAMEマクロを使用して、扱う必要のある各タイプのcppファイル(例えば、最初にタイプを定義したcppファイル)で使用することができます。
リンカーは、それがどこかで定義されている限り、適切なテンプレート特殊化を見つけることができ、そうでなければリンカーエラーを投げるので、私は型を追加することができます。
どのように解決するのですか?
Jesse Bederの解決策がベストだと思いますが、もしtypeidが与える名前が気に入らない場合(例えばgccはマングルドネームを与えると思います)、以下のようにすることができます。
template<typename T>
struct TypeParseTraits;
#define REGISTER_PARSE_TYPE(X) template <> struct TypeParseTraits<X> \
{ static const char* name; } ; const char* TypeParseTraits<X>::name = #X
REGISTER_PARSE_TYPE(int);
REGISTER_PARSE_TYPE(double);
REGISTER_PARSE_TYPE(FooClass);
// etc...
そして、以下のように使用します。
throw ParseError(TypeParseTraits<T>::name);
EDITです。
また、この2つを組み合わせることもできます。
name
をデフォルトで呼び出す関数に変更します。
typeid(T).name()
をデフォルトで呼び出し、それが許容できない場合のみ特別化するようにします。
関連
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】c++で.txtファイルから2次元の配列に読み込む
-
[解決済み] template "と "typename "キーワードはどこに、なぜ入れなければならないのですか?
-
[解決済み] 型名の後の括弧は、newで違いがあるのでしょうか?
-
[解決済み] C++テンプレート関数定義の.CPPファイルへの格納
-
[解決済み] Explanation of <script type = "text/template"> ... </script>
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み】デバッグアサーションに失敗しました。C++のベクトル添え字が範囲外
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み] 警告:暗黙の定数変換でのオーバーフロー
-
[解決済み】標準C++で変数の型を表示することは可能ですか?