2011-01-09 16 views
5

以下の「解決策」はコンパイルされますが、私の望むものではありません。 putメンバ関数をfor_eachに渡し、*thisには渡しません。ブーストを使用すると、にはのオプションがあります。これはC++ 03で解決できますか?C++ 03のfor_eachにメンバー関数を渡す(ブーストなし、C++ 11なし)

#include <algorithm> 
#include <functional> 
#include <vector> 
using namespace std; 

class Wheel { }; 

class Car { 

public: 

    void process(const vector<Wheel>& wheel) { 

     for_each(wheel.begin(), wheel.end(), *this); 
    } 

    void operator()(const Wheel& w) { put(w); } 

private: 

    void put(const Wheel& w) { } 
}; 

int main() { 

    vector<Wheel> w(4); 

    Car c; 

    c.process(w); 

    return 0; 
} 
+0

なぜ正確に説明できますか? – EmeryBerger

答えて

12

はい、それは、mem_funbind1stテンプレートの組み合わせを使用することができます

void process(const vector<Wheel>& wheel) { 
    for_each(wheel.begin(), wheel.end(), bind1st(mem_fun(&Car::put), this)); 
} 

mem_funへの呼び出しは、二つの引数に取る新しい関数オブジェクトを作成 - 受信機として動作するようにCar*Wheelを呼び出し、最初のパラメータを受信側に、2番目のパラメータを引数としてputを呼び出します。 bind1stを呼び出すと、この関数の最初のパラメータとしてレシーバオブジェクトがロックされます。

しかし、このコードを少し変更して機能させる必要があると思います。 bind1stアダプタは、const参照で引数を取る関数ではうまく動作しません。putを参照するのではなく値でWheelに変更する必要があります。

+0

これらはTR1のみであり、C++ 03はありません。 – Puppy

+1

@ DeadMG-いいえ、これらはC++ 03の仕様です。しかし、新しいmem_fnがこれに代わるものではありません。 – templatetypedef

+1

@ Ali-参照を使用できない理由は、内部的に、 'bind1st'テンプレートは元の関数の引数型が何であっても、その引数を参照しようとします。元の関数が参照によってパラメータを受け取る場合、これは参照の参照を作成しようとしますが、これは許可されません。ただし、パラメータがポインタである場合は、それは問題ありません。ポインタへの参照を持つことができます。 – templatetypedef

1

確かに、単にboost :: mem_funcに相当するものを書くことができます。 TR1にも1つあります。あなたが議論の数を増やしたいが、概念的に難しいのではないなら、それは少し繰り返す。

template<typename T, typename mem_func_type> struct mem_func_internal; 
template<typename T, typename Ret> struct mem_func_internal<T, Ret (T::*)()> { 
    typedef Ret(T::* functype)(); 
    T* obj; 
    functype func; 
    Ret operator()() { 
     return obj->*func(); 
    } 
}; 
template<typename T, typename Ret, typename ArgType1> struct mem_func_internal<T, Ret (T::*)(ArgType1) { 
    typedef Ret(T::* functype)(); 
    T* obj; 
    functype func; 
    Ret operator()(ArgType1 arg) { 
     return obj->*func(arg); 
    } 
} 
template<typename T, typename mem_func_type> struct mem_func : public mem_func_internal<T, mem_func_type> { 
    mem_func(T* object, mem_func_type mem_func) 
     : obj(object) 
     , func(mem_func) {} 
}; 
template<typename T, typename mem_func_type> mem_func<T, mem_func_type> bind_mem_func(T* object, mem_func_type func) { 
    return mem_func<T, mem_func_type>(object, func); 
} 
// Usage 
std::for_each(wheel.begin(), wheel.end(), bind_mem_func(this, &Car::put)); 

このようなコードを書いて以来、しばらくお待ちいただいています。しかし、それはその要点です。ラムダを使わずに使用例を書くのは難しいです。

+0

申し訳ありませんが、私はこのレベルにいません。あなたは私に例を教えていただけますか?どちらを使うべきですか?ありがとう。 – Ali

+0

@Ali: '// Usage'コメントの下に書かれている行は、使い方の例です。 – Puppy

+0

申し訳ありませんが、私は最後のUsageラインを見逃しました。私は2つの簡単なコンパイルエラーを修正したが、それ以降は残りのものを修正することはできない... :( – Ali

3

mem_fun_ref:hereを参照してください。上記の例では、ホイールのメンバーではない車であることをputを変更すること

for_each(wheel.begin(), wheel.end(), mem_fun_ref(&Wheel::put)); 

注:オブジェクトのベクトルを持っているところ

mem_fun_ref

はあなたのケースで動作するはずです。それはあなたにもそれを使用する方法のアイデアを与える必要があります。

オブジェクトへのポインタベクトルを使用している場合はmem_funを使用してください。

+0

申し訳ありませんが、これはコンパイルされません。私はCar :: putが必要であり、Wheel :: putはこの例のようにしたくないことに注意してください(私はCar :: putでコンパイルしようとしました) – Ali

+0

これはうまくいくかもしれませんが、 @ templatypypedefの答えのようにbind1stを使う必要があります。 –

+0

@Fred:それはうまくいきますが、templatetypedefの答えは、Wheelのメンバ関数を置かなくてもうまくいきます。 – sashang

関連する問題