質問

理解できなくて困っています mem_fun_ref. 。正直に言うと、速度と利益を得るためにファンクターをインライン化できるため、私は通常、この種の処理にファンクターを使用します。ただし、このコードがボトルネックになるわけではないので、これを試してみたいと思いました。

これが私がやりたいことの例です。他にも方法があることは知っています。使いたくない copy, 、範囲メンバー関数を使用したくありません。 back_inserter. 。特に使いたいのは mem_fun_ref. 。これは単なる例であり、実際のケースはさらに複雑です。そうは言っても、なぜこれが間違っているのかは本当にわかりませんが、私はよく知りません mem_fun_ref または 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, 、そして私のコードでもそれを変更することはできません。これを機能させるための簡単な変更はありますか?ワンライナーの解決策が必要です。

役に立ちましたか?

解決

ただ、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));

他のヒント

この問題は、Herb Sutter 著の「例外的な C++ スタイル」(28 ~ 30 ページ) で説明されています。おそらく、安全にポインタを作成することはできません。 vector<int>::push_back メンバー関数の正確な署名を確認する必要があるため、メソッドを使用しても明らかではない可能性があります。 vector<int>::push_back 標準ライブラリにあります。これは (標準ライブラリ内で) 次の理由からです。

  1. デフォルトのパラメーターを持つメンバー関数のシグネチャーは、「同等の動作を持つ 2 つ以上のメンバー関数のシグネチャー」に置き換えられる可能性があります。
  2. メンバー関数のシグネチャには、追加のデフォルトのパラメーターが含まれる場合があります。

最後に、ハーブ・サッター氏は次のようにアドバイスしました。

  1. 標準ライブラリではなく mem_fun を使用してください
  2. 標準ライブラリではなく、メンバー関数へのポインターを使用する

私はあなただけの単純化されたコード例を与えてくれた、おそらくので、あなたは、back_inserterを使用しないと述べてきたことを知っています。

あなたが何をしようとして、の正確を行う方法を疑問に誰のために、そしてそれを使用して幸せ、back_inserterを使用します:

std::copy(a.begin(), a.end(), std::back_inserter(b));
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top