怎样让C++函数重载时连返回值类型也加入重载决议?

众所周知,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);
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值