怎样让C++函数重载时连返回值类型也加入重载决议?
来源:互联网 发布:淘宝代购兼职 编辑:程序博客网 时间:2024/04/27 23:29
众所周知,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);}
- 怎样让C++函数重载时连返回值类型也加入重载决议?
- 根据返回值类型重载函数
- C++学习笔记-----函数调用时的决议:名字查找,重载决议,可访问性检测
- 从operator<<谈函数重载决议
- 函数重载:仅根据函数返回值类型不能实现重载
- C#实现函数根据返回类型重载
- 返回类型重载
- JAVA 重载,返回类型
- C++函数重载(4) - 函数的返回类型
- 运算符重载函数的参数类型以及返回值类型
- 运算符重载--函数返回值
- 运算符重载--函数返回值
- IntelliSense 无法重载仅按返回类型区分的函数
- 为什么函数重载不可以根据返回类型区分?
- 只能靠参数而不能靠返回值类型的不同来区分重载函数
- C++中的函数重载中为什么不考虑返回值类型?
- Delphi函数重载时参数类型问题
- C/C++的区别(默认值、内联函数、函数重载、const、引用、参数、返回值)
- ActionScript 3.0著名开源库 大集合
- Java内存泄露的理解与解决
- java内存分配
- ORACLE初探
- C++中public protected private关键字
- 怎样让C++函数重载时连返回值类型也加入重载决议?
- 石榴——转自田维《花田半亩》
- C#反射
- Android中几种延后处理事件的方法
- 假如ACMer有技能,你会选择哪个职业..
- 【汇编】手把手教你打造自己的第一个操作系统
- SQL Server 2008配置过程
- GetStockObject 检索预定义的备用笔、刷子、字体或者调色板
- linux netstat 命令巧用和apache负载查看方法