Pertanyaan Melewati fungsi anggota untuk for_each di C ++ 03 (tidak ada dorongan, no c ++ 11)


"Solusi" di bawah ini mengkompilasi tetapi bukan itu yang saya inginkan. Saya ingin lulus put fungsi anggota untuk for_each dan tidak *this. Menggunakan dorongan TIDAK sebuah pilihan. Bisakah ini diselesaikan dalam C ++ 03?

#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;
}

5
2018-01-09 23:16


asal


Jawaban:


Ya itu bisa, menggunakan kombinasi dari mem_fun dan bind1st templat:

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

Panggilan ke mem_fun membuat objek fungsi baru yang mengambil dua argumen - a Car* untuk bertindak sebagai penerima dan Wheel, lalu menelepon put dengan parameter pertama sebagai penerima dan parameter kedua sebagai argumen. Panggilan bind1st kemudian kunci objek penerima sebagai parameter pertama dari fungsi ini di tempat.

Namun, saya pikir Anda perlu membuat satu perubahan kecil pada kode ini agar dapat berfungsi. Itu bind1st adaptor tidak berfungsi baik dengan fungsi yang mengambil argumennya berdasarkan referensi const, jadi Anda mungkin perlu berubah put sehingga dibutuhkan a Wheel dengan nilai daripada dengan referensi.


12
2018-01-09 23:26



Anda dapat menggunakan mem_fun_ref: lihat sini.

mem_fun_ref harus bekerja dalam kasus Anda di mana Anda memiliki vektor objek:

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

Perhatikan bahwa contoh di atas berubah put menjadi anggota Roda dan bukan Mobil. Ini seharusnya memberi Anda gambaran tentang cara menggunakannya.

Menggunakan mem_fun jika Anda memiliki vektor pointer ke suatu objek


3
2018-01-09 23:41



Tentu saja - Anda bisa menulis setara dengan dorongan Anda sendiri :: mem_func. TR1 juga memilikinya. Ini sedikit repetitif jika Anda ingin meningkatkan jumlah argumen, tetapi tidak sulit secara konseptual.

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));

Sudah lama sejak saya menulis kode seperti ini, jadi mungkin agak sedikit. Tapi itulah intinya. Sangat sulit untuk menulis contoh penggunaan tanpa menggunakan lambda.


1
2018-01-09 23:28