4

我很难弄清楚mem_fun_ref。我必须承认,我通常将仿函数用于这类事情,因为它们可以内联以提高速度和利润。但是,这段代码不会成为瓶颈,所以我想尝试一下。

这是我想做的一个例子。我知道还有其他方法可以做到这一点。我不想使用copy,我不想使用范围成员函数,我不想使用back_inserter. 我特别想用mem_fun_ref. 这只是一个简单的例子,实际情况要复杂得多。也就是说,我真的不知道为什么这是错误的,但我不熟悉mem_fun_refor mem_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-liner 的解决方案。

4

4 回答 4

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));
于 2009-06-04T07:39:01.687 回答
2

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

  1. 具有默认参数的成员函数签名可能会替换为“两个或多个具有等效行为的成员函数签名。
  2. 成员函数签名可能具有其他默认参数。

最后,赫伯·萨特建议

  1. 使用 mem_fun,而不是标准库
  2. 使用指向成员函数的指针,而不是标准库
于 2009-06-29T22:34:59.043 回答
0

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

对于其他想知道如何完全按照您正在尝试做的事情并乐于使用它的人,请使用back_inserter

std::copy(a.begin(), a.end(), std::back_inserter(b));
于 2009-06-04T07:50:36.233 回答
0

也就是说,总是有other_mem_fun,我在知道 boost 之前就已经做好了。这可能适合。

于 2009-06-04T07:57:16.517 回答