众所周知,C++函数重载时返回值是不参与重载决议的, 也就是说:
int lex_cast(const char*);
double lex_cast(const char*);
这样两个函数在同一个编译单元同一个 namespace 中时, 会编译报错.
怎么办呢?
一个小技巧:
#include <iostream> #include <string> #include <boost/lexical_cast.hpp> class my_cast { const char* s; public: template<class Target> operator Target() const { return boost::lexical_cast<Target>(s); } my_cast(const char* s) : s(s) {} }; int main() { using namespace std; long long ll = my_cast("12345678910111213"); int ii = my_cast("-123"); string ss = my_cast("abcde"); double dd = my_cast(('3' + string(".2222")).c_str()); cout << ll << endl; cout << ii << endl; cout << ss << endl; cout << dd << endl; return 0; }
小得几乎不值一提. 但是, 这段代码中, 可能有些仔细的人会提出疑问:
('3' + string(".2222")).c_str()
这里返回的 const char* 是属于临时变量的, 而 my_cast 竟然把这个临时变量保存到它的成员, 这里能成功并无错应该只是因为被释放的 c_str() 那块内存恰好未被重新分配, 太危险了!
其实, 这没任何问题, C++ 标准规定: 临时变量的生存期是包含它的那个表达式(整个), 而非任何一个真子表达式. 仔细体味这句话吧!
上面只是在 my_cast 非模板的情况, 如果 my_cast 包含模板参数, 并且 my_cast 成员也必须是模板, 怎么办?
template<class Source> class my_cast_imp { Source s; public: template<class Target> operator Target() const { return boost::lexical_cast<Target>(s); } my_cast_imp(const Source& s) : s(s) {} }; template<class Source> my_cast_imp<Source> my_cast2(const Source& s) { return my_cast_imp<Source>(s); }
只需定义一个辅助模板类, 再加一个模板函数去实例化模板类.
核心思想只有一个: 使用 operator class conversion, 下面是一个比较实用的 cast, 没有用 boost::lexical_cast, 没有编译龟速的问题. (boost 过度使用 template 了)
#include <stdlib.h> #include <string> class goldcast_imp { const char* s; int base; public: goldcast_imp(const char* s, int base) : s(s), base(base) {} operator int () const { return (int) strtol (s, NULL, base); } operator unsigned() const { return (unsigned)strtoul(s, NULL, base); } operator signed long () const { return strtol (s, NULL, base); } operator signed long long() const { return strtoll (s, NULL, base); } operator unsigned long () const { return strtoul (s, NULL, base); } operator unsigned long long() const { return strtoull(s, NULL, base); } operator float() const { return strtof(s, NULL); } operator double() const { return strtod(s, NULL); } operator long double() const { return strtold(s, NULL); } operator std::string() const { return std::string(s); } }; goldcast_imp goldcast(const std::string& s, int base = 10) { return goldcast_imp(s.c_str(), base); } goldcast_imp goldcast(const char* s, int base = 10) { return goldcast_imp(s, base); }
原文链接: https://www.cnblogs.com/rockeet/archive/2011/09/07/3666896.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/31885
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!