我一直在写一个win32文件系统库,我决定不使用TCHAR,而是想编写一个模板(仅限标题)库,它可以在char / wchar_t上工作,而不管编译器范围/窄选项。
这给我留下了两个问题:
我已经创建了我认为对这两个问题的合理优雅的解决方案,但我希望堆栈溢出社区告诉我是否存在与它们相关的任何隐藏成本/恶意。
首先(解决1)因为我的模板类将T作为字符类型,所以我在类中的“detail”命名空间中创建了以下模板/宏:
// Selector template to choose between W and A versions of win32 functions
template<typename WF, typename AF> inline WF& select_w32func(AF &, WF & pFuncW, wchar_t) { return pFuncW; }
template<typename WF, typename AF> inline AF& select_w32func(AF & pFuncA, WF &, char) { return pFuncA; }
template<typename T> inline T get_traits() { return NULL; }
#define SELECT_W32FUNC(x) auto x = detail::select_w32func(::##x##A, ::##x##W, detail::get_traits<T>());
#define SELECT_W32FUNCS(x,y) auto x = detail::select_w32func(::x, ::y, detail::get_traits<T>());
接下来(解决2)我创建了以下模板和宏:
template<typename WC, typename AC> inline const WC* select_chartrait(const AC*, const WC* b, wchar_t) { return b; }
template<typename WC, typename AC> inline const AC* select_chartrait(const AC* a, const WC*, char) { return a; }
template<typename WC, typename AC> inline const WC select_chartrait(const AC, const WC b, wchar_t) { return b; }
template<typename WC, typename AC> inline const AC select_chartrait(const AC a, const WC, char) { return a; }
// Macro which allows string literals to be adapted by template parameter T
#define _S(x) detail::select_chartrait((x), (L##x), detail::get_traits<T>())
这允许我编写类的构造函数和成员函数,就好像我没有处理模板化参数一样,例如,下面的构造函数构造一个带有CSIDL特殊文件夹标识符的w32file对象,因为它是它的父元素: / p>
basic_w32file(DWORD dwCSIDL, std::basic_string<T> & child) : m_name( MAX_PATH, ' ' )
{
SELECT_W32FUNC(PathCombine);
SELECT_W32FUNCS(strlen, wcslen);
basic_w32file<T> parent( getSystemDirectory ( dwCSIDL, _S(' ')));
if (child == _S(".") || child == _S(".."))
PathCombine(&m_name[0], parent.getAbsoluteName().c_str(), child.c_str());
else
PathCombine(&m_name[0], parent.getPath().c_str(), child.c_str());
m_name.resize( strlen(&m_name[0]) );
}
如您所见,SELECT_W32FUNC宏会覆盖全局命名空间的PathCombine定义,并将其替换为函数的A或W版本的函数引用。 _S(“..”)将正确的字符串文字放在适当的位置。
我的感觉是,这将是非常有效的,因为模板选择器函数将被内联并且基本上没有运行时逻辑,这意味着它们应该被优化到几乎没有,这是正确的假设吗?