绑定第2个问题与用户定义的类 [英] Bind2nd issue with user-defined class

查看:157
本文介绍了绑定第2个问题与用户定义的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图学习如何使用bind2nd和用户定义的类,但我得到一个错误,我不能弄清楚如何解决,尽管我努力寻找其他资源的帮助。





main.cpp b
$ b

  #include< algorithm> 
#include< vector>

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

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

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

std :: transform(bases.begin(),bases.end(),bases.begin(),std :: bind2nd(F(),2)
//错误C2664:'_OutIt std :: transform< std :: _ Vector_iterator< _Myvec>,std :: _ Vector_iterator< _Myvec> ;,
// std :: binder2nd< _Fn2> _Init,_OutIt,_Fn1)':不能将参数4从
//'std :: binder2nd< _Fn2>'转换为'std :: binder2nd< _Fn2>'
}


解决方案

首先,您必须包含



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

为了获得类型traits信息,如* 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>碱基;

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

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

//打印到stdout
std :: copy(bases.begin(),bases.end(),std :: ostream_iterator< int>(std :: cout, ));
std :: cout<< std :: endl;
}

编辑

如果您访问了一个C ++ 11意识的编译器和stdlib,您的向量填充代码可以很容易地重写为:

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

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

使用C ++ 11有一个新的绑定器绑定。这是更灵活,你可以试试,如果你想。如:

 使用命名空间std :: placeholder; 
std :: transform(std :: begin(bases),std :: end(bases),std :: begin(bases),
std :: bind );

(我刚才看到,从下面的答案,a.lasram提到了新的std ::我不知道你的项目中是否允许使用新的C ++ 11,而不是旧的C ++ 03的功能,如果我是你,我会,如果你不允许,然后(引用着名的亚历山大先生)呼叫你的代理。:))



Btw。 Ryan(看评论)是绝对正确的,当他提到,即使我最精心的std :: generate东西;)可以更短写使用 iota

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

std :: iota在数字中定义。



希望有所帮助。


I'm trying to learn how to use bind2nd with user-defined classes, but I'm getting an error that I can't figure out how to fix despite my efforts of looking into other resources for assistance.

Help would be appreciated, thank you.

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>'
}

解决方案

First of all you've to include functional to use the binder functionality.

Second you need to specify your operator() to be const.

Third, in order to get the type traits information, like *first_argument_type* and so on, it is best, in your case, to inherit from 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;
}

Edit

If you've access to a C++11 aware compiler and stdlib, your vector filling code can be easily rewritten to:

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

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

With C++11 there is a new binder (moved from boost::bind) std::bind. This is far more flexible and you might give it a try, if you want to. Such as:

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

(I just have seen, from the answer below, that a.lasram mentioned the new std::bind. I don't know if you're allowed in your project, or whatever, to use new C++11, instead of old C++03 functionality. If I were you, I would, if you're not allowed, well then (to quote from famous Mr. Alexandrescu) "Call your agent." :) )

Btw. Ryan (see the comments) is absolutely right, when he mentions, that even my most elaborate std::generate thing ;) can be shorter written using iota:

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

std::iota is defined in numeric. So you've to include that as well.

Hope that helps.

这篇关于绑定第2个问题与用户定义的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆