首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用户定义类的Bind2nd问题

用户定义类的Bind2nd问题
EN

Stack Overflow用户
提问于 2013-07-21 20:30:45
回答 2查看 746关注 0票数 0

我正在努力学习如何在用户定义的类中使用bind2nd,但是我遇到了一个错误,尽管我努力寻找其他资源来提供帮助,但我还是想不出如何解决这个问题。

非常感谢你的帮助,谢谢。

main.cpp

代码语言:javascript
复制
#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>'
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-21 20:38:22

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

其次,需要将运算符()指定为const。

第三,为了获得类型特征信息,如*first_argument_type*等,最好是从std::binary_function继承。

代码语言:javascript
复制
#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,您的向量填充代码可以很容易地重写到:

代码语言:javascript
复制
std::vector<int> bases(5);
int i = 0;

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

有了C++11,就有了一个新的绑定器(从boost::bind移动) std::bind。这要灵活得多,如果你愿意的话,你可以试一试。例如:

代码语言:javascript
复制
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功能。如果我是你,我会,如果你不被允许,那么(引用著名的亚历山大斯库先生的话)“打电话给你的经纪人。”

顺便说一句。瑞安(见评论)是完全正确的,当他提到,即使是我最精心制作的std::generate ;)也可以用iota缩短编写。

代码语言:javascript
复制
std::iota(bases.begin(), bases.end(), 1);

iota是用数字定义的。所以你也得把它也包括进去。

希望这能有所帮助。

票数 2
EN

Stack Overflow用户

发布于 2013-07-21 20:40:02

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

现在,二进制函子必须适应std::bind2ndbind2nd期望F能给出first_argument_typesecond_argument_typeresult_type的类型。

代码语言:javascript
复制
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,这是一种更通用、更灵活的解决方案,它没有这些必需的类型防御。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17776601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档