我正在尝试学习如何将bind2nd与用户定义的类一起使用,但是我遇到了一个错误,即使我努力寻找其他资源以获得帮助,我也无法弄清楚如何修复。
帮助将不胜感激,谢谢。
的main.cpp
#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>'
}
答案 0 :(得分: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感知编译器和stdlib,则可以轻松地将矢量填充代码重写为:
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 中定义。所以你也要把它包括在内。
希望有所帮助。
答案 1 :(得分:2)
这完成了Stefan的回答,他指出std::bind
将const引用作为仿函数参数,因此operator ()
必须是const。
现在,您的二元仿函数必须适应std::bind2nd
。
bind2nd
希望F
输入first_argument_type
,second_argument_type
和result_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