0

我正在尝试学习如何将 bind2nd 与用户定义的类一起使用,但我遇到了一个错误,尽管我努力寻找其他资源以寻求帮助,但我无法弄清楚如何解决。

帮助将不胜感激,谢谢。

主文件

#include <algorithm>
#include <vector>

class F
{
public:
  int operator()(int a, int b)
  {
    return a * b;
  }
};

int main(void)
{
  std::vector<int> bases;

  for(int i = 0; i < 5; ++i)
    bases.push_back(i);

  std::transform(bases.begin(), bases.end(), bases.begin(), std::bind2nd(F(), 2));
  // Error C2664: '_OutIt std::transform<std::_Vector_iterator<_Myvec>,std::_Vector_iterator<_Myvec>,
  // std::binder2nd<_Fn2>>(_InIt,_InIt,_OutIt,_Fn1)' : cannot convert parameter 4 from
  // 'std::binder2nd<_Fn2>' to 'std::binder2nd<_Fn2>'
}
4

2 回答 2

2

首先,您必须包含功能才能使用活页夹功能。

其次,您需要将您的 operator() 指定为 const。

第三,为了获得类型特征信息,如 *first_argument_type* 等,在您的情况下,最好从 std::binary_function 继承。

#include <algorithm>
#include <vector>
#include <functional>
#include <iterator>
#include <iostream>

struct F : public std::binary_function<int, int, int>
{
    int operator()(int a, int b) const
    {
        return a * b;
    }
};

int main(void)
{
    std::vector<int> bases;

    for(int i = 0; i < 5; ++i)
        bases.push_back(i);

    std::transform(bases.begin(), bases.end(), bases.begin(), std::bind2nd(F(), 2));

    // print it to stdout
    std::copy(bases.begin(), bases.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;
}

编辑

如果您可以访问支持 C++11 的编译器和标准库,您的向量填充代码可以很容易地重写为:

std::vector<int> bases(5);
int i = 0;

std::generate(bases.begin(), bases.end(), [&i]() { return ++i; });

对于 C++11,有一个新的绑定器(从 boost::bind 移出)std::bind。这要灵活得多,如果您愿意,可以尝试一下。如:

using namespace std::placeholders;
std::transform(std::begin(bases), std::end(bases), std::begin(bases), 
               std::bind(F(), 2, _1));

(我刚刚从下面的答案中看到,a.lasram 提到了新的 std::bind。我不知道您的项目中是否允许您使用新的 C++11,而不是旧的 C++03 功能。如果我是你,我会,如果你不被允许,那么(引用著名的 Alexandrescu 先生的话)“打电话给你的代理。”:))

顺便提一句。Ryan(见评论)是绝对正确的,当他提到时,即使是我最精心制作的 std::generate 东西;)也可以用以下方式写得更短iota

std::iota(bases.begin(), bases.end(), 1);

std::iota 在numeric中定义。所以你也必须包括在内。

希望有帮助。

于 2013-07-21T20:38:22.557 回答
2

这完成了 Stefan 的回答,他指出std::bind将 const 引用作为仿函数参数,因此operator ()必须是 const。

现在,您的二元仿函数必须适用于std::bind2nd. bind2nd期望Ftypedef和. first_argument_type_second_argument_typeresult_type

class F
{
public:
    typedef int first_argument_type;
    typedef int second_argument_type;
    typedef int result_type;

    int operator()(int a, int b) const
    {
        return a * b;
    }
};

C++11 引入std::bind了一种更通用、更灵活的解决方案,它没有这些必需的 typedef

于 2013-07-21T20:40:02.293 回答