【问题标题】:How can I make a templated function that takes a parameter that is the result of boost::bind?如何制作一个模板化函数,该函数采用 boost::bind 结果的参数?
【发布时间】:2016-10-14 21:22:58
【问题描述】:

我有一个辅助方法,它将boost::function<> 类型的对象作为输入,并用另一个处理其他物流的函子包装该函数。

这是我的签名的样子:

class Example {
public:
    typedef ... Callback;

    ...

    template<typename T>
    static Callback make_wrapper( const boost::function<void( T )>& );
};

如果我尝试将调用 boost::bind 的结果传递给 make_wrapper,我会收到关于类型不兼容的编译错误(Apple LLVM 版本 7.3.0)

class OtherClass {
public:
    void method ( uint32_t );
};

OtherClass* other;

Example::Callback c = Example::make_wrapper ( boost::bind( &OtherClass::method, other, _1 ) );

这给出了:

error: no matching function for call to 'make_wrapper'
note: candidate template ignored: could not match 'function' against 'bind_t'

我找到了两种解决方法:

  1. 临时变量:

    boost::function<void( uint32_t )> f = boost::bind( &OtherClass::method, other, _1 );
    Example::Callback c = Example::make_wrapper ( f );
    
  2. 调用 make_wrapper 的特定特化:

    Example::Callback c = Example::make_wrapper<uint32_t> ( boost::bind( &OtherClass::method, other, _1 ) );
    

如果我可以跳过额外的提示并使用内联调用调用 make_wrapper 来绑定,我会更喜欢它。

有没有一种方法可以声明 make_wrapper 模板的签名以帮助编译器确定类型,而无需使用上述解决方法之一?

【问题讨论】:

  • 使用autodecltype

标签: c++ boost boost-bind


【解决方案1】:

每当您使用bind 时,您都会丢弃有关绑定函数的参数类型的所有信息。函数模板不可能推导出参数类型T,因为bind的返回值是一个函数对象,可以用任意数量的任意类型的参数调用。

您可以将bind 函数包装到辅助函数模板中,以推断绑定的成员函数,尤其是其结果类型和参数(示例使用std::bindstd::function,但我相信它可以轻松转换为boost ):

#include <iostream>
#include <string>
#include <functional>

struct foo {
  void bar(int a, std::string s) {
     std::cout << a << " " << s << std::endl;
  }
};


template<typename T1, typename T2>
void make_wrapper(const std::function<void( T1, T2 )>&) {
}

template <class Foo, class Res, class... Args, class... Placeholders>
std::function<Res(Args...)> my_bind(Res (Foo::*bar)(Args...), Foo& f, Placeholders... ps) {
   return std::bind(bar, f, ps...);
}

int main() {
  foo f;
  make_wrapper(my_bind(&foo::bar, f, std::placeholders::_1, std::placeholders::_2));
}

只要foo::bar 没有超载,代码就可以工作,在这种情况下您无法避免static_cast

【讨论】:

    【解决方案2】:

    std::bindboost::bind 都将返回类型列为未指定。这意味着,如果您想要便携,您根本无法知道这一点。

    【讨论】:

      猜你喜欢
      • 2017-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多