在编译上一篇日志 ScopeGuard:编写Exception-Safe代码 中的ScopeGuard程序时发生了一个错误,代码加下:
void
Decrement(
int
&
x) {
--
x; }
int test_ByRef( int & count) {
ScopeGuard guard = MakeGuard(Decrement, ByRef(count));
}
int test_ByRef( int & count) {
ScopeGuard guard = MakeGuard(Decrement, ByRef(count));
}
代码很简单就是传一个函数指针和变量应用给MakeGuard,看似没任何问题,但编译就出错:
ScopeGuard.cpp: In instantiation of `ScopeGuardImpl1
<
void
()(
int
&
), RefHolder
<
int
>
>
'
:
ScopeGuard.cpp: 114 : instantiated from here
ScopeGuard.cpp: 47 : error: field `ScopeGuardImpl1 < void ()( int & ), RefHolder < int > > ::fun_ ' invalidly declared function type
ScopeGuard.cpp: 114 : instantiated from here
ScopeGuard.cpp: 47 : error: field `ScopeGuardImpl1 < void ()( int & ), RefHolder < int > > ::fun_ ' invalidly declared function type
出错信息指出成员变量fun_不是有效的函数类型,网上查了一下发现原因是Decrement只是一个函数指针(function pointer),并不能被用作type去定义一个变量,需要用std::ptr_fun将其转换成函数对象(function object),修改如下:
int
test_ByRef(
int
&
count) {
ScopeGuard guard = MakeGuard(std::ptr_fun(Decrement), ByRef(count));
}
ScopeGuard guard = MakeGuard(std::ptr_fun(Decrement), ByRef(count));
}
但std::ptr_fun有其局限,它只能处理一元函数(unary function)和二元函数(binary function),所以最佳选择还是使用boost::bind。
参考文章:
1. ptr_fun