我正在尝试将通用boost::function<void(void)>
连接到不同签名的许多boost :: signals2。我可以使用boot :: lambda :: bind通过将返回值作为绑定参数的一部分传递来执行绑定部分,但是当返回类型为void时会出现问题
示例:
template<typename S>
class signal
{
Connection VoidConnect(boost::function<void(void)> callback)
{
//if(boost::is_same<void, typename S::result_type>::value) // Doesn't seem to work
if ( boost::is_void<typename S::result_type>::value ) // Doesn't seem to work
{
//GetSignal returns the actual boost signal
// typename 'S' will be a boost::function with the same signature as the signal
return GetSignal().connect( boost::lambda::bind(callback) );
}
else
{
typename S::result_type f;
return GetSignal().connect( (boost::lambda::bind(callback), f ) );
}
}
}
我不断收到编译错误
error: variable or field ‘f’ declared void
include/boost/function/function_template.hpp:132:42: error: void value not ignored as it ought to be
从错误中可以看出,带有boost :: is_void(既不是boost :: is_same)的if条件似乎不起作用,有人知道为什么吗?有没有更好的方法来进行这种绑定?
谢谢, SAK
答案 0 :(得分:2)
您在运行时检查此条件,因此两个分支在编译时需要正确(并且它们显然不是)。 相反,只需将您的模板专门用于void:
// WARNING: untested code!
template<typename S>
class signal
{
Connection VoidConnect(boost::function<void(void)> callback)
{
typename S::result_type f;
return GetSignal().connect( (boost::lambda::bind(callback), f ) );
}
};
template<>
class signal <void>
{
Connection VoidConnect(boost::function<void(void)> callback)
{
return GetSignal().connect( boost::lambda::bind(callback) );
}
};
如果要在成员函数上使用enable_if,则应将其定义为模板。请参阅以下代码:
#include <boost/signals2.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
using namespace boost::signals2;
class connect
{
public:
template<typename S>
connection VoidConnect(boost::function<void(void)> callback, S &sig,
typename boost::disable_if<boost::is_void<typename S::result_type> >::type *dummy = 0)
{
typename S::result_type res;
return sig.connect( (boost::lambda::bind(callback), *res) );
}
template<typename S>
connection VoidConnect(boost::function<void(void)> callback, S &sig,
typename boost::enable_if<boost::is_void<typename S::result_type> >::type *dummy = 0)
{
return sig.connect( boost::lambda::bind(callback) );
}
};
int main()
{
boost::function<void(void)> f;
signal<void(int)> sig1;
connect s1;
s1.VoidConnect(f, sig1);
signal<int(int)> sig2;
connect s2;
s2.VoidConnect(f, sig2);
}