如何使用boost::在c+中是相同的+;模板和boost::lambda::bind

如何使用boost::在c+中是相同的+;模板和boost::lambda::bind,boost,boost-bind,boost-function,boost-lambda,boost-signals2,Boost,Boost Bind,Boost Function,Boost Lambda,Boost Signals2,我正在尝试将一个通用的boost::function连接到许多具有不同签名的boost::signals2。我可以使用boot::lambda::bind通过将返回值作为bind参数的一部分传递来完成绑定部分,但是当返回类型为void时会出现问题 例如: template<typename S> class signal { Connection VoidConnect(boost::function<void(void)> callback) { //if

我正在尝试将一个通用的
boost::function
连接到许多具有不同签名的boost::signals2。我可以使用boot::lambda::bind通过将返回值作为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 ) );
    }
  }
}
从错误中可以看出,带有boost::is_void的if条件(boost::is_也不相同)似乎不起作用,有人知道为什么吗?有没有更好的方法进行此绑定

谢谢,
Sak

您在运行时检查此条件,因此两个分支在编译时都需要正确(而且它们显然不正确)。 相反,只需为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) );         
  } 
};
//警告:未测试的代码!
模板
类信号
{ 
连接无效连接(boost::函数回调)
{ 
typename S::结果\类型f;
返回GetSignal().connect((boost::lambda::bind(callback),f));
} 
};
模板
类信号
{ 
连接无效连接(boost::函数回调)
{ 
返回GetSignal().connect(boost::lambda::bind(回调));
} 
};
如果要在成员函数上使用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);
}
#包括
#包括
#包括
#包括
#包括
使用名称空间boost::signals2;
类连接
{ 
公众:
模板
连接无效连接(boost::函数回调、S&sig、,
typename boost::disable_if::type*dummy=0)
{
typename S::result\u type res;
返回sig.connect((boost::lambda::bind(回调),*res));
}
模板
连接无效连接(boost::函数回调、S&sig、,
typename boost::enable_if::type*dummy=0)
{
返回sig.connect(boost::lambda::bind(回调));
}
}; 
int main()
{
boost::函数f;
信号sig1;
连接s1;
s1.空连接(f,sig1);
信号sig2;
连接s2;
s2.真空连接(f,sig2);
}

Hmm,感谢soln,这个模板类信号是一个具有许多功能的大类,如果没有为void专门化整个模板的选项,还有其他选项吗?我目前正在研究boost::enable_if是否可以用于在编译时实现选择。上面的示例适用于大多数签名类型,但在信号签名包含组合器时无法编译,例如:“signal sig3”知道为什么吗?@Sak什么是
Combiners::LogicalOrCombiner
,会出现什么错误?很抱歉,它是一个内部结构,而不是一个boost组合器,它是一个调用每个插槽的组合器,如果其中任何一个返回true,那么返回给调用者的值也是true。组合器与一个信号(typedef boost::signals2::signal MySignalType)一起使用,组合器只是一个返回true或false的函子。与此同时,我有一个类似的查询,其中非常令人费解!
#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);
}