4


3

mem_fun_refのトラブル

`+ mem_fun_ref +`を理解するのに苦労しています。 私は認めなければなりません、それらはスピードと利益のためにインライン化されることができるので、私は通常この種のもののために関手を使います。 しかし、このコードがボトルネックになることはないので、これを試してみました。

これが私がやりたいことの例です。 他にも方法があることを私は知っています。 `+ copy `を使用したくない、範囲メンバー関数を使用したくない、 ` back_inserter `を使用したくない。 具体的には、 ` mem_fun_ref `を使用します。 これはほんの簡単な例ですが、実際のケースははるかに複雑です。 とはいえ、なぜこれが間違っているのかは本当にわかりませんが、 ` mem_fun_ref `や ` mem_fun +`については詳しくありません。

これが私が働きたいことです。

#include
#include
#include
#include

using namespace std;

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

    // should work like magic!
    for_each(a.begin(), a.end(), bind1st(mem_fun_ref(&vector::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,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,const int &>
1>        ]

`+ reference to reference is illegal `は、関数が値でパラメーターを取る必要があると思い込ませます。 しかしもちろん、これは ` vector +`で変更することは不可能であり、私のコードでも変更することはできません。 これを機能させるための簡単な変更はありますか? 1ライナーのソリューションが必要です。

4 Answer


4


`+ bind `を使用してください。 ` mem_fun +`バージョンは難しすぎます。

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

`+ ref +`を使用する必要のないもう1つの方法は、変更するベクトルへのポインターを渡すことです。

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


2


この問題は、Herb Sutterによる「Exceptional C Style」(28-30ページ)で説明されています。 メンバー関数の正確なシグネチャを確認する必要があるため、 `+ vector

push_back +`メソッドへのポインタを安全に作成できない可能性があります。 これは、(標準ライブラリの)理由です。

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

  2. メンバー関数シグネチャには、追加のデフォルトがあります パラメーター。

結局、ハーブサッターはそれを助言した

  1. 標準ライブラリではなく、mem_funを使用する

  2. 標準ライブラリではなく、メンバ関数へのポインタを使用する


0


おそらく単純化されたサンプルコードを与えたために、 `+ back_inserter +`を使用したくないと言ったことを知っています。

あなたがしようとしていることを_正確に_どのように行うのか疑問に思っており、それを喜んで使用する場合は、 `+ back_inserter +`を使用してください:

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


0


そうは言っても、常にhttp://www.differentpla.net/content/2003/02/other-mem-fun-and-std-for-each [+ other_mem_fun +]があり、ブーストについて知る前に作成しました。 。 これは合うかもしれません。