Boost.Function实现函数指针和回调以及测试模板(1)

Boost.Function 库包含一组作为function object wrappers的类模板,在概念上类似于一个泛化的callback,它在两种情况下具有和函数指针相同的特性,一种是定义一个可用于某些可调用实现的调用接口,一种是在整个程序的流程衷可能变化的调用。

Boost.Function在一定程度上可以代替函数指针,允许用户在实现上拥有更大的弹性,目标可以是任何兼容的函数对象(或函数指针),这意味着传给接口的函数被Boost.Funciton指定未可以转换为目标函数对象的参数。

#include <boost/function.hpp>
#include <iostream>
#include <functional>

 

 

函数指针的用法

// 函数指针用法

boost::function<float (int x, int y)> f;

// 创建一个函数对象,赋给f
struct int_div
{
	float operator() (int x, int y) const
	{
		return (float)x/y;
	}
};

f = int_div;

//这里应该检查一下函数指针是否为空
if(f)
{
	std::cout<<f(5,3)<<std::endl;	 等同于 float result = 5/3
}
else
{
	std::cout<"f has no target, so it is unsafe to call"<<std::endl;
}


//函数指针用法--自由函数

boost::function<void (int values[], int n, int &sum , float &avg)> f_sum_avg;

void do_sum_avg(int values[], int n, int &sum , float &avg)
{
	sum = 0;
	for(int i=0;i<n; i++)
	{
		sum +=  values[i];
	}
	avg = (float)sum/n;
}

f_sum_avg = &do_sum_avg;	



// 成员函数,member fucntion
boost::function<int (Class_X*, int)> f;
f = &Class_X::foo;

Class_X x;
f(&x, 5);	//等同于int(Class_X::foo, 5);



//应用bind
boost::function<void (int x)>f;
Class_X x;
Class_X::foo(int x);

f = boost::bind(&Class_X::foo,this);
f(5);		//等同于x.foo(5);

 

回调函数的实现

//回调函数
boost::function <void (int x, int y)> f;

class A:
{
public:
	Function_Creat()
	{
		  //data;
		
		int x = 5;
		int y = 10;
		
		if (m_callback)
		{
			m_callback(x,y);
		}
		else
		{
			std::cout<<"error"<<std::endl;
		}
	}
	
	RegisterCallBackFunction(f callback)
	{
		m_callback = callBack;
	}
	
	f m_callback;
};


class B:
{
public:
	GetCallBackValue(int x, int y);
	{
		st::cout<<x<< y<<std::endl;
	}
};


A a_obj;
B b_obj;
//可以考虑多线程
boost::thread(A.Function_Creat(),a_obj,"");
a_obj.RegisterCallBackFunction(boost:bind(B::GetCallBackValue,b_obj));



 

测试用例

 

// For more information, see http://www.boost.org

#include <boost/test/minimal.hpp>
#include <boost/function.hpp>
#include <functional>
#include <string>
#include <utility>

using namespace boost;
using namespace std;

int global_int;

struct write_five_obj { void operator()() const { global_int = 5; } };
struct write_three_obj { int operator()() const { global_int = 3; return 7; }};
static void write_five() { global_int = 5; }
static void write_three() { global_int = 3; }
struct generate_five_obj { int operator()() const { return 5; } };
struct generate_three_obj { int operator()() const { return 3; } };
static int generate_five() { return 5; }
static int generate_three() { return 3; }
static string identity_str(const string& s) { return s; }
static string string_cat(const string& s1, const string& s2) { return s1+s2; }
static int sum_ints(int x, int y) { return x+y; }


struct write_const_1_nonconst_2
{
  void operator()() { global_int = 2; }
  void operator()() const { global_int = 1; }
};

struct add_to_obj
{
  add_to_obj(int v) : value(v) {}

  int operator()(int x) const { return value + x; }

  int value;
};



无参示例

static void test_zero_args()
{
  typedef function<void ()> func_void_type;

  write_five_obj five;
  write_three_obj three;

  // Default construction
  func_void_type v1;
  BOOST_CHECK(v1.empty());

  // Assignment to an empty function
  v1 = five;
  BOOST_CHECK(v1 != 0);

  // Invocation of a function
  global_int = 0;
  v1();
  BOOST_CHECK(global_int == 5);

  // clear() method
  v1.clear();
  BOOST_CHECK(v1 == 0);

  // Assignment to an empty function
  v1 = three;
  BOOST_CHECK(!v1.empty());
}


 

一个形参示例


static void test_one_arg()
{

  function<int (int)> f1(neg);
  BOOST_CHECK(f1(5) == -5);

  function<string (string)> id(&identity_str);
  BOOST_CHECK(id("str") == "str");

  function<string (const char*)> id2(&identity_str);
  BOOST_CHECK(id2("foo") == "foo");

  add_to_obj add_to(5);
  function<int (int)> f2(add_to);
  BOOST_CHECK(f2(3) == 8);

  const function<int (int)> cf2(add_to);
  BOOST_CHECK(cf2(3) == 8);
}

 

 

两个参数示例


static void test_two_args()
{
  function<string (const string&, const string&)> cat(&string_cat);
  BOOST_CHECK(cat("str", "ing") == "string");

  function<int (short, short)> sum(&sum_ints);
  BOOST_CHECK(sum(2, 3) == 5);
}

 

测试浮点型


static void test_emptiness()
{
  function<float ()> f1;
  BOOST_CHECK(f1.empty());

  function<float ()> f2;
  f2 = f1;
  BOOST_CHECK(f2.empty());

  function<double ()> f3;
  f3 = f2;
  BOOST_CHECK(f3.empty());
}

测试成员函数示例

struct X {
  X(int v) : value(v) {}

  int twice() const { return 2*value; }
  int plus(int v) { return value + v; }

  int value;
};


static void test_member_functions()
{
  boost::function<int (X*)> f1(&X::twice);

  X one(1);
  X five(5);

  BOOST_CHECK(f1(&one) == 2);
  BOOST_CHECK(f1(&five) == 10);

  boost::function<int (X*)> f1_2;
  f1_2 = &X::twice;

  BOOST_CHECK(f1_2(&one) == 2);
  BOOST_CHECK(f1_2(&five) == 10);

  boost::function<int (X&, int)> f2(&X::plus);
  BOOST_CHECK(f2(one, 3) == 4);
  BOOST_CHECK(f2(five, 4) == 9);
}

成员函数引用示例

struct add_with_throw_on_copy {
  int operator()(int x, int y) const { return x+y; }

  add_with_throw_on_copy() {}

  add_with_throw_on_copy(const add_with_throw_on_copy&)
  {
    throw runtime_error("But this CAN'T throw");
  }

  add_with_throw_on_copy& operator=(const add_with_throw_on_copy&)
  {
    throw runtime_error("But this CAN'T throw");
  }
};


static void test_ref()
{
  add_with_throw_on_copy atc;
  try {
    boost::function<int (int, int)> f(ref(atc));
    BOOST_CHECK(f(1, 3) == 4);
  }
  catch(runtime_error e) {
    BOOST_ERROR("Nonthrowing constructor threw an exception");
  }
}

测试异常捕获示例


static void test_exception()
{
  boost::function<int (int, int)> f;
  try {
    f(5, 4);
    BOOST_CHECK(false);
  }
  catch(boost::bad_function_call) {
    // okay
  }
}

测试回调函数示例

 

typedef boost::function< void * (void * reader) > reader_type;
typedef std::pair<int, reader_type> mapped_type;


static void test_implicit()
{
  mapped_type m;
  m = mapped_type();
}

static void test_call_obj(boost::function<int (int, int)> f)
{
  BOOST_CHECK(!f.empty());
}

static void test_call_cref(const boost::function<int (int, int)>& f)
{
  BOOST_CHECK(!f.empty());
}

static void test_call()
{
  test_call_obj(std::plus<int>());
  test_call_cref(std::plus<int>());
}

 

 

 

Main Test 函数


int test_main(int, char* [])
{
  test_zero_args();
  test_one_arg();
  test_two_args();
  test_emptiness();
  test_member_functions();
  test_ref();
  test_exception();
  test_implicit();
  test_call();

  return 0;
}

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值