无C++11环境下模板函数参数默认值的实现方案问询
C++03下模板函数默认参数的调用问题解决方案
老哥,我太懂你在C++03环境下的这个困扰了——想给模板函数加个默认的模式参数,结果编译器根本不帮你推导模板类型,导致myFunc(20);这种调用直接报错是吧?
问题根源
在C++03标准里,模板函数的默认函数参数不会被用来推导模板参数的类型。你写的template <typename T> void myFunc(int value, T mode = mode1()),当调用myFunc(20)时,编译器找不到T的推导依据,自然会报错。
针对示例代码的解决方案
最直接的办法是写一个非模板的重载函数,显式调用指定模板参数的版本:
#include <iostream> #include <type_traits> struct mode1 {}; struct mode2 {}; // 保留原模板函数(可以去掉默认参数,因为重载会处理默认场景) template <typename T> void myFunc(int value, T mode) { if(std::is_same<T, mode1>::value) { std::cout << "foo"; } else if(std::is_same<T, mode2>::value) { std::cout << "bar"; } } // 新增重载:处理默认调用,显式指定T为mode1 void myFunc(int value) { myFunc<mode1>(value, mode1()); } // 测试调用 int main() { myFunc(20); // 输出"foo" myFunc(30, mode2()); // 输出"bar" return 0; }
这样调用myFunc(20)时,会自动匹配这个重载函数,进而触发模板的mode1版本,完全符合你的需求。
针对实际Tokenize函数的适配
把同样的思路用到你的Tokenize函数上就行——新增一个不带TokenType参数的重载,显式调用TokenType=tokenTypeChar的模板实例:
// 原模板函数(移除TokenType参数的默认值,交给重载处理) template <typename TokenType> HGStringBasic Tokenize(const _ElemT* tokens, size_type uTokenIndex, size_type uIndex = 0, size_type uEndIndex = npos, TokenType tokenType) const { size_type uPosInStr; size_type uCurrToken; if(uEndIndex == npos) { uEndIndex = this->Length(); } for( uCurrToken = 0 ; uIndex < uEndIndex ; (uIndex = uPosInStr+1), (++uCurrToken) ) { if(std::is_same<TokenType, tokenTypeChar>::value) uPosInStr = this->PosBrk(tokens, uIndex); else if(std::is_same<TokenType, tokenTypeString>::value) uPosInStr = this->Pos(tokens, uIndex); if(uCurrToken == uTokenIndex) { if(uPosInStr == npos) return this_type(&m_data[uIndex], uEndIndex - uIndex); return this_type(&m_data[uIndex], (uPosInStr < uEndIndex ? uPosInStr : uEndIndex) - uIndex); } if(uPosInStr == npos) break; } return this_type(); } // 新增重载:默认使用tokenTypeChar HGStringBasic Tokenize(const _ElemT* tokens, size_type uTokenIndex, size_type uIndex = 0, size_type uEndIndex = npos) const { return Tokenize<tokenTypeChar>(tokens, uTokenIndex, uIndex, uEndIndex, tokenTypeChar()); }
额外说明
这种重载方式完全兼容C++03,而且编译期就能完成模板实例化和std::is_same的判断,不会有任何运行时开销,完美契合你想要的优化需求。
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

