DIY一个C++ traits来判断enum是否有用户自定义的operator<<

前段时间发现自己的String库中有个bug:

String& operator+=(int);

String& operator+=(unsigned);

// 所有的整型、浮点型都有一个operator+=的重载

template <typename T>
String& operator+=(const T& t)
{
    std::stringstream ss;
    ss << t;
    this->operator+=(ss.str());
    return *this;
}
对所有的整型、浮点型、std::string,String::operator+=都有一个高效的实现,但唯独忽略了对enum的特殊处理,即使enum能通过integral promotion自动转换为int。

这样,在用“+=”连接字符串和enum类型的时候,String类会调用template版本的operator+=,具体操作包括一个局部std::stringstream变量的创建和析构,一次(低效的)stringstream::operator<<的调用,一个临时std::string变量的创建和析构(由ss.str()引起)。

这样的操作序列,性能之低可以想象。我的代码中对enum和String类有大量使用,导致程序的性能下降了30%。

问题的解决非常容易,TR1中(以及C++ 11中)有个叫做is_enum的traits,根据这个traits,很容易就能把来自enum的String::operator+=的调用定向到enum对应的int类型的String::operator+=的调用。

但是这样就引入了一个新问题,如果某个enum EnumA自己定义了operator<<:

std::ostream& operator<<(std::ostream&, EnumA);
那么按照老代码,它能够经由template版本的String::operator+=调用到这个operator<<,而打了patch后的String,在调用+=的时候却会出现不一致的行为:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值