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

众所周知,C++函数重载时返回值是不参与重载决议的, 也就是说:

int lex_cast(const char*);

double lex_cast(const char*);

这样两个函数在同一个编译单元同一个 namespace 中时, 会编译报错.

怎么办呢?

一个小技巧:

小得几乎不值一提. 但是, 这段代码中, 可能有些仔细的人会提出疑问:

这里返回的 const char* 是属于临时变量的, 而 my_cast 竟然把这个临时变量保存到它的成员, 这里能成功并无错应该只是因为被释放的 c_str() 那块内存恰好未被重新分配, 太危险了!

其实, 这没任何问题, C++ 标准规定: 临时变量的生存期是包含它的那个表达式(整个), 而非任何一个真子表达式. 仔细体味这句话吧!

上面只是在 my_cast 非模板的情况, 如果 my_cast 包含模板参数, 并且 my_cast 成员也必须是模板, 怎么办?

只需定义一个辅助模板类, 再加一个模板函数去实例化模板类.

核心思想只有一个: 使用  operator class conversion, 下面是一个比较实用的 cast, 没有用 boost::lexical_cast, 没有编译龟速的问题. (boost 过度使用 template 了)

 

作者:
该日志由 csdn-whinah 于2011年09月07日发表在C++分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
转载请注明: 怎样让C++函数重载时连返回值类型也加入重载决议?
标签:
【上一篇】
【下一篇】

您可能感兴趣的文章:

17 个回复

  1. weiqubo说道:

    此思想是错误的, lex_cast(const char*);你如何判断是调用哪一个? 即,此刻不我需要函数的返回值.

  2. whinah说道:

    [reply]weiqubo[/reply]
    啥事都不干,operator xxx 不会执行

  3. weiqubo说道:

    [reply]whinah[/reply]
    不会执行? 显然我调用了一个函数,你却让它也不干?当然如果我int a = lex_cast(const char*)时,这个函数又开始执行指令了,二义性消除了吗?
    用返回值当作重载的判断从理论上是行不通的,否则C++设计者早就将其加入了.

  4. whinah说道:

    [reply]weiqubo[/reply]
    无语, 我对牛弹琴了

  5. zy498420说道:

    作者把重载决议通过封装推迟到赋值的时候了。然而有时我们需要返回值做主语,不得不手动来一个强制转换来激发重载决议了,建议作者把这一点加上。

  6. zy498420说道:

    作者把重载决议通过封装推迟到赋值的时候了。然而有时我们需要返回值做主语,不得不手动来一个强制转换来激发重载决议了,建议作者把这一点加上。

  7. whinah说道:

    [reply]zy498420[/reply]
    Good advice, Thank you!

  8. zy498420说道:

    [reply]whinah[/reply]
    毕竟在c++的空间里,返回值除了做函数的宾语,还可以做主语。比方说我要你这个cast 返回的std::string右值通过swap成员函数赋值给另一个std::string, 而不是直接赋值。

  9. whinah说道:

    C++ 标准规定: 临时变量的生存期是包含它的那个表达式(整个), 而非任何一个真子表达式. 这一点非常关键, 在我看到标准文本中的这句话之前, 我是不敢写这样的代码的: goldcast 可能返回一个 temp string 的 c_str()!
    所以 int x = goldcast(string("123")); 是合法代码, 而 goldcast_imp gci = goldcast(string("123")); int x = gci; 是非法的, 当然这里多余 string 的构造是故意的.

  10. zy498420说道:

    [reply]whinah[/reply]
    一个右值持有另一个右值的引用(或者持有另一个右值的数据成员的引用),都是安全的,不会有野引用,呵呵。除非画蛇添足的去写析构函数,那就不保证了。

  11. whinah说道:

    [reply]zy498420[/reply]
    必须保证它们都在同一个表达,跨越表达式就不能保证安全了。

  12. zy498420说道:

    [reply]whinah[/reply]
    呵呵,访问右值肯定只能在一行表达式中的。始终用右值访问或引用右值,所有的一切都不会逾越这行表达式。除非用左值去访问或引用了右值。

  13. whinah说道:

    [reply]zy498420[/reply]
    逗号分隔的,也算是在同一个表达式:
    const char* p;
    p = string("abc").c_str(), printf("%sn", p); 这是安全的,合法的

  14. zy498420说道:

    [reply]whinah[/reply]
    逗号当然也是运算符哦。只要不要过了这一行 继续使用p

  15. lonelyrains说道:

    看过您关于C++重载扩展的这篇文章,想到了很久以前遇到的一个问题:
    针对所有动态库中的函数的调用,写一个测试MFC工程。
    比如动态库中有一个函数int add(int a,int b),用户只用在文本框中输入int add(int 3,int 4)和该函数所在的dll路径,点击运行,马上就可以输出返回值。
    我所知的调用dll中函数的方式:先定义函数指针类型:typedef int (WINAPI ADD)(int a,int b);然后定义该指针类型的指针,赋值为LoadLibrary的返回值。问题是要针对动态库中所有的函数,就涉及到很多种数据类型和参数列表组合。如何针对复杂多变的函数参数列表,定义对应的指针类型以供调用?
    如今,我的理解是写一个C/C++运行时库,解析用户输入的文本字符串,动态生成一个符合条件的函数指针。但是具体怎么实现,还是没想好。有什么建议?

发表评论

您必须 登录 后才能发表评论。