2

我尝试以这种方式使用旧的 bind2nd 函数:

template<typename T>
class printer
{
public:
  void operator()(T a, string& kd)
  {
        cout<<a<<endl;
  }
};


int main(int argc, char *argv[])
{
   string nme = "J-dar";
   auto f1 = bind2nd(printer<int>(),nme);

   //f1(5);
   return 0;
}

但我得到了很多错误:

required from here
error: no type named 'first_argument_type' in 'class printer<int>'  class binder2nd        ^
error: no type named 'second_argument_type' in 'class printer<int>'    typename _Operation::second_argument_type value;                                              ^
error: no type named 'second_argument_type' in 'class printer<int>'    binder2nd(const _Operation& __x,    ^
error: no type named 'result_type' in 'class printer<int>'    operator()(const typename _Operation::first_argument_type& __x) const    ^
error: no type named 'result_type' in 'class printer<int>'    operator()(typename      _Operation::first_argument_type& __x) const    ^
required from here
error: no type named 'second_argument_type' in 'class printer<int>'    typedef typename _Operation::second_argument_type _Arg2_type;                                           

从我所看到的一切都是正确的,所以我真的不知道发生了什么。^

4

1 回答 1

8

首先:我建议使用在 C+11 中已弃用的bind1st()and bind2nd(),以及对 C++03 标准库的函数式编程的过时支持。

您应该使用 C++11's ,因为您似乎可以负担得起 - 从您使用关键字std::bind()的事实来看:auto

#include <functional>

// ...

auto f1 = std::bind(printer<int>(), std::placeholders::_1, nme);

这就是说,只是为了记录,不推荐使用的std::bind2nd()函数需要一些关于仿函数调用运算符签名的元数据,并且它希望这些元数据在仿函数类中作为类型别名提供。例如:

template<typename T>
class printer
{
public:

    // These metadata must be present in order for bind1st and bind2nd to work...
    typedef void result_type;
    typedef T first_argument_type;
    typedef string const& second_argument_type;

    void operator()(T a, string const& kd) const
//                                         ^^^^^ // Bonus advice #1:
//                                               // This could and should be
//                                               // const-qualified
//                              ^^^^^
//                              Bonus advice #2: why not taking by
//                              reference to const here? ;)
    {
        cout<<a<<endl;
    }
};

实现上述目的的一种更简单的方法是使用(也已弃用的)类模板std::binary_function作为基类,并让该类模板定义适当的类型别名:

template<typename T>
class printer : public std::binary_function<T, string const&, void>
//              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
public:
    void operator()(T a, string const& kd) const
    {
        cout<<a<<endl;
    }
};

但同样,请考虑将std::bind1st(),std::bind2nd()std::unary_function,std::binary_function放回抽屉。它们被 C++11 更强大的函数式编程支持所取代。

于 2013-05-18T14:46:44.523 回答