boost::call_traits

 写C++ template程序的时候,经常遇见的问题之一就是,如何让一个函数同时支持pass by value和pass by reference,例如:

class  Primitive
{
public:
    
void set(int value) ...{ m_value = value; }
private:
    
int m_value;
}
;

class  Object
{
public:
    
void set(const Object& value) ...{ m_value = value; }
private:
    Object m_value;
}
;

template 
< typename T >
class  Test
{
public:
    
// DO NOT DO THIS:
    
// 1) Compile error
    
// 2) Choose which one???
    void set(T value) ...{ m_value = value; }
    
void set(const T& value) ...{ m_value = value; }
private:
    Object m_value;
}
;

boost::call_traits就是用来解决这个问题的:
   #include <boost/call_traits.hpp>

template  < typename T >
class  Test
{
public:
    
void set(typename boost::call_traits<T>::param_type value{ m_value = value; }
private:
    T m_value;
}
;

这样的话:
Test<int> 会生成 void set(int value);
Test<Object> 会生成 void set(const Object& v);

boost是如何做到的呢?下面是一个简化的实现。boost的实现要多很多细节,但是原理是类似的。
template  < typename T,  bool  small >
struct  call_traits_i  { typedef const T& type; } ;
 
template 
< typename T >
struct  call_traits_i < T,  true >   { typedef T type; } ;
 
template 
< typename T >
struct  call_traits  { typedef typename call_traits_i<T, sizeof(T)<=sizeof(void*)>::type param_type; } ;


一点感慨:
现在C++库的建设,我感觉是走上了一条不归路。C++的库,不但要实现功能,还要实现的好,实现的高效。而其他语言的类库,最重要的是“我们有这个功能”。解掉效率的包袱,别人是一日千里,而C++们呢,望穿秋水了。。。就像Ruby设计的哲学之一就是“为程序员优化,而不是为编译器优化”。当年一直抵触去拥抱Java,感觉自己用C++,开发的效率也不慢。现在接触到了动态语言后(尤其是Ruby),真是感觉,这世界变化快呀。奶酪迟早要不见的,或缩小的,不会以个人的意愿为转移的。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值