C++利用模板检测是否包含某个函数,并决定生成什么样的调用代码

// Author:
//   hustos@qq.com
//
#include <stdio.h>
#include <new>

template <bool c>
struct BoolType
{
  static const bool value = c;
};
typedef BoolType<false> FalseType;
typedef BoolType<true> TrueType;


template<bool, typename T> struct __has_assign__;

template <typename T>
struct __has_assign__<true, T>
{
  typedef int (T::*Sign)(const T &);
  typedef char yes[1];
  typedef char no[2];
  template <typename U, U>
      struct type_check;
  template <typename _1> static yes &chk(type_check<Sign, &_1::assign> *);
  template <typename> static no &chk(...);
  static bool const value = sizeof(chk<T>(0)) == sizeof(yes);
};

template <typename T>
struct __has_assign__<false, T>
{
  static bool const value = false;
};
template <typename T>
inline int construct_assign_wrap(T &dest, const T &src, TrueType)
{
  printf("%s\n", "has ::assign method");
  new(&dest) T();
  return dest.assign(src);
}

template <typename T>
inline int construct_assign_wrap(T &dest, const T &src, FalseType)
{
  printf("%s\n", "does not have ::assign method");
  new((&dest)) T(src);
  return 1;
}

template <typename T>
inline int construct_assign(T &dest, const T &src)
{
  return construct_assign_wrap(dest, src,
      BoolType<__has_assign__<__is_class(T), T>::value>());
}


// ======= ======= 使用上面的方法来做个实验 ======= =======

class A
{
public:
  A() = default;
  A(const A &other)
  {
    printf("call A::A, this is unsafe method, can not return error code to user\n");
    a_ = other.a_;
  }
  ~A() = default;
  // note: 这里必须加上 const,否则签名不匹配,会走到 A::A
  int assign(const A &other) {
    a_ = other.a_;
    printf("call A::assigned, this is safe method, can return error code to user\n");
    return 0;
  }
private:
  int a_;
};

int main(int argc, const char *argv[])
{
  A a;
  A b;
  // 自动判断 A 是否有 assign 方法并决定如何将 a 拷贝到 b:
  // - 1. 调assign 
  // - 2. 使用A的拷贝构造函数
  construct_assign(b, a);
  return 0;
}

编译测试下:

[xiaochu.yh ~/tools] $g++ assign.cpp -std=c++0x -o assign
[xiaochu.yh ~/tools] $./assign
has ::assign method
call A::assigned, this is safe method, can return error code to user
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值