【发布时间】:2010-11-06 12:40:13
【问题描述】:
我正在编写一些模板类来解析一些文本数据文件,因此很可能绝大多数解析错误是由于数据文件中的错误造成的,这些错误大部分不是由程序员编写的,所以需要一个关于为什么应用程序无法加载的好消息,例如类似:
解析 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 文件中)。
然后链接器能够找到适当的模板特化,只要它在某处定义,否则抛出链接器错误以便我可以添加类型。
【问题讨论】:
-
与您的问题并不真正相关,但您可能还想在访问该部分时使用 map.find(section) ,除非您有意创建一个空白部分。
标签: c++ templates compile-time typename