我正在编写一些模板类来解析一些文本数据文件,因此很可能绝大多数解析错误是由于数据文件中的错误造成的,这些错误大部分不是由程序员编写的,所以需要关于为什么应用程序无法加载的好消息,例如:
解析 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;}
然后我可以在 cpp 文件中为我需要处理的每种类型使用 DEFINE_TYPE_NAME 宏(例如,在定义要开始的类型的 cpp 文件中)。
然后链接器能够找到适当的模板特化,只要它在某处定义,否则抛出链接器错误,以便我可以添加类型。