【问题标题】:How to define and use boost::function with "optional arguments"?如何定义和使用带有“可选参数”的 boost::function?
【发布时间】:2011-03-04 10:35:48
【问题描述】:

我正在使用一个需要某种回调方法的类,所以我使用 boost::function 来存储函数指针。

我需要回调有一个可选参数,但我发现 boost::function 不允许我定义可选参数类型,所以我尝试了以下代码并且它有效..

//the second argument is optional  
typedef boost::function< int (int, char*)> myHandler;  

class A   
{  
public:  
     //handler with 2 arguments  
     int foo(int x,char* a) {printf("%s\n",a);   return 0;}; 
     //handler with 1 argument
     int boo(int x) {return 1;};       
}

A* a = new A;  
myHandler fooHandler= boost::bind(&A::foo,a,_1,_2);  
myHandler booHandler= boost::bind(&A::boo,a,_1);    

char* anyCharPtr = "just for demo";  
//This works as expected calling a->foo(5,anyCharPtr)  
fooHandler(5,anyCharPtr);  
//Surprise, this also works as expected, calling a->boo(5) and ignores anyCharPtr 
booHandler(5,anyCharPtr);   

我对它起作用感到震惊,问题是它应该起作用吗,它是否合法?
有没有更好的解决方案?

【问题讨论】:

  • IMO 这里奇怪的不是你的//surprise 在哪里,而是你可以将booHandler 声明为myHandler 类型。
  • 如果只有 fooHandler 也无法将文字绑定到 char *

标签: c++ boost function-pointers optional-parameters boost-bind


【解决方案1】:

可以说是绑定 -> 函数转换中的类型安全漏洞。 boost::bind 不返回 std::function 而是返回一个非常复杂类型的函数对象。在

的情况下
boost::bind(&A::boo,a,_1);

如上所见,返回的对象有类型

boost::_bi::bind_t<
  int, 
  boost::_mfi::mf1<int,A,int>,
  boost::_bi::list2<boost::_bi::value<A*>, boost::arg<1> > 
>

std::function 只检查提供的函数对象是否“兼容”,在这种情况下,它是否可以使用 int 作为第一个参数和指向字符的指针 作为第二个参数。通过检查 *boost::bind_t* 模板,我们发现它确实有一个匹配的函数调用运算符:

template<class A1, class A2> result_type operator()(A1 & a1, A2 & a2)

在这个函数内部,第二个参数最终被默默地丢弃。这是设计使然。来自文档:Any extra arguments are silently ignored (...)

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多