使用for_each / mem_fun有什么问题

时间:2014-03-04 18:11:49

标签: c++

我正在使用C ++ 98。

我有以下代码:

#include <vector>
#include <algorithm>
#include <functional>

struct Foo {};

void
add_each(std::vector<std::vector<Foo*> > &vv, const Foo *f)
{
    for_each(vv.begin(), vv.end(), std::bind2nd(std::mem_fun(&std::vector<Foo*>::push_back), f));
}

基本上我喜欢在每个向量的末尾添加一个元素。

G ++抱怨for_each。

In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/algorithm:62,
                 from 1.c:2:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_algo.h: In function ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<std::vector<Foo*, std::allocator<Foo*> >*, std::vector<std::vector<Foo*, std::allocator<Foo*> >, std::allocator<std::vector<Foo*, std::allocator<Foo*> > > > >, _Funct = std::binder2nd<std::mem_fun1_t<void, std::vector<Foo*, std::allocator<Foo*> >, Foo* const&> >]’:
1.c:10:   instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_algo.h:4200: error: no match for call to ‘(std::binder2nd<std::mem_fun1_t<void, std::vector<Foo*, std::allocator<Foo*> >, Foo* const&> >) (std::vector<Foo*, std::allocator<Foo*> >&)’
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/backward/binders.h:146: note: candidates are: typename _Operation::result_type std::binder2nd<_Operation>::operator()(const typename _Operation::first_argument_type&) const [with _Operation = std::mem_fun1_t<void, std::vector<Foo*, std::allocator<Foo*> >, Foo* const&>]
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/backward/binders.h:152: note:                 typename _Operation::result_type std::binder2nd<_Operation>::operator()(typename _Operation::first_argument_type&) const [with _Operation = std::mem_fun1_t<void, std::vector<Foo*, std::allocator<Foo*> >, Foo* const&>]

你看到了什么问题吗?

3 个答案:

答案 0 :(得分:1)

for_each将取消引用迭代器并将该结果传递给其一元函数参数。在您的情况下,该类型为std::vector<Foo*>&。但是,std::mem_fun需要指针指向它所包装的对象,而不是引用。您应该使用std::mem_fun_ref代替。

void
add_each(std::vector<std::vector<Foo*> > &vv, const Foo *f)
{
    for_each(vv.begin(), vv.end(), 
             std::bind2nd(std::mem_fun_ref(&std::vector<Foo*>::push_back), f));
}

Live example

答案 1 :(得分:0)

您正尝试将push_back const Foo*加入Foo*的向量中。使向量保持const Foo*或将参数f的类型更改为Foo*

答案 2 :(得分:0)

如果您希望您的代码也使用C ++ 2011的标准库进行编译,那么我建议使用以下解决方案

void ( std::vector<Foo *>:: *pf )( Foo * const &);
pf = &std::vector<Foo *>::push_back;

std::for_each( vv.begin(), vv.end(), 
               std::bind2nd( std::mem_fun_ref( pf ), f ) );

问题是在C ++ 2011中,成员函数push_back被重载。