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;
}