mem_fun_ref麻烦

时间:2009-06-04 07:20:09

标签: c++ stl function-pointers

我无法搞清楚mem_fun_ref。我不得不承认,我通常会使用仿函数来做这类事情,因为它们可以内联速度和利润。但是,这段代码不会成为瓶颈,因此我想尝试这件事。

以下是我想要做的一个例子。我知道还有其他方法可以做到这一点。我不想使用copy,我不想使用范围成员函数,我不想使用back_inserter。我特别想使用mem_fun_ref。这只是一个简单的例子,真实案例要复杂得多。也就是说,我真的不知道为什么这是错的,但我不熟悉mem_fun_refmem_fun

这就是我想要的工作:

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

using namespace std;

int main()
{
    list<int> a;
    a.push_back(1);
    a.push_back(2);
    a.push_back(3);
    vector<int> b;

    // should work like magic!
    for_each(a.begin(), a.end(), bind1st(mem_fun_ref(&vector<int>::push_back), b));
}

但我得到3个错误:

1>c:\program files\microsoft visual studio 9.0\vc\include\functional(276) : error C2529: '_Right' : reference to reference is illegal
1>c:\program files\microsoft visual studio 9.0\vc\include\functional(281) : error C2529: '_Right' : reference to reference is illegal
1>c:\program files\microsoft visual studio 9.0\vc\include\functional(282) : error C2535: 'void std::binder1st<_Fn2>::operator ()(const int &(&)) const' : member function already defined or declared
1>        with
1>        [
1>            _Fn2=std::mem_fun1_ref_t<void,std::vector<int>,const int &>
1>        ]
1>        c:\program files\microsoft visual studio 9.0\vc\include\functional(276) : see declaration of 'std::binder1st<_Fn2>::operator ()'
1>        with
1>        [
1>            _Fn2=std::mem_fun1_ref_t<void,std::vector<int>,const int &>
1>        ]

reference to reference is illegal让我觉得函数需要按值获取参数。但是,当然,这不可能在vector中进行更改,也不可能在我的代码中更改它。是否有一个简单的改变让这个工作?我需要一个1线的解决方案。

4 个答案:

答案 0 :(得分:4)

只需使用bind即可。 mem_fun版本太难了。

for_each(a.begin(), a.end(),
  boost::bind(&vector<int>::push_back, boost::ref(b), _1));

另一种不需要使用ref的方法是将指针传递给要修改的向量:

for_each(a.begin(), a.end(),
  boost::bind(&vector<int>::push_back, &b, _1));

答案 1 :(得分:2)

Herb Sutter在第28-30页的“Exceptional C ++ Style”中解释了这个问题。有人可能无法安全地创建指向vector<int>::push_back方法的指针,因为需要确定成员函数的确切签名,即使对于标准库中的vector<int>::push_back,这可能也不明显。这是因为(在标准库中):

  1. 具有默认参数的成员函数签名可能会被“具有同等行为的两个或更多成员函数签名替换。
  2. 成员函数签名可能包含其他默认参数。
  3. 最后,Herb Sutter建议

    1. 使用mem_fun,不使用标准库
    2. 将指针用于成员函数,而不是使用标准库

答案 2 :(得分:0)

我知道您已经说过您不想使用back_inserter,可能是因为您只提供了简化的示例代码。

如果其他人想知道如何完全您正在尝试做什么,并乐意使用它,请使用back_inserter

std::copy(a.begin(), a.end(), std::back_inserter(b));

答案 3 :(得分:0)

那就是说,总有other_mem_fun,在我知道提升之前,我已经熟了。这可能适合。