私はいくつかのテキストデータファイルを解析するためのいくつかのテンプレートクラスを書いています。そのため、解析エラーの大部分はデータファイルのエラーが原因である可能性があります。データファイルのエラーの大部分はプログラマーによって作成されていないため、必要です。アプリの読み込みに失敗した理由についての良いメッセージ。たとえば、次のようなものです。
example.txtの解析中にエラーが発生しました。[MySectiom] Keyの値( "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));
}
}
データファイルがたくさんあるので、データファイルが使用する可能性のあるすべてのタイプに対して特定のオーバーロードを作成する必要はありません...
また、例外が発生しない限り実行時のオーバーヘッドが発生しないソリューションが必要です。つまり、このコードは何回も呼び出され、ロード時間はすでにいくらか長くなっているため、完全なコンパイル時のソリューションが必要です。
編集:わかりました、これは私が思いついた解決策です:
私は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ファイルで)。
リンカは、どこかで定義されている限り、適切なテンプレートの特殊化を見つけることができます。そうでない場合は、リンカエラーをスローして、型を追加できます。