Question

titre Déroutant, espérons un code clarifiera:

struct MyNestedType {
    void func();
};

struct MyType {
    MyNestedType* nested;
}

std::vector<MyType> vec;

// ... populate vec

// I want something approximating this line, but that doesn't use made-up C++!
std::for_each(vec.begin(), vec.end(), std::mem_fun_ref(&MyType::nested->func));

Donc, fondamentalement, je veux appeler une méthode sur chaque élément du conteneur, mais ce n'est pas en fait une méthode de type, il est une méthode sur un type contenu ... Je sais que je pourrais écrire un objet de fonction « transmettre l'appel, mais il y a quelques méthodes que je voudrais appeler et qui se salissant.

Toutes les idées?

Était-ce utile?

La solution

Vous pouvez utiliser ces foncteur

template <typename T, T* MyType::* TMember, void (T::* TNestedMember)() >
struct Caller {
    Caller() {
    }

    template <typename TObject>
    void operator()(TObject object) {
        (object.*TMember->*TNestedMember)();
    }
};

Pour résoudre votre problème

struct MyNestedType {
    MyNestedType(int a):
        a_(a){
    }
    void func() {
        std::cout << "MyNestedType::func " << a_ << std::endl;
    }
    void foo() {
        std::cout << "MyNestedType::foo " << a_ << std::endl;
    }
    int a_;
};
struct MyType {
    MyNestedType* nested;
};

int main()
{
    std::vector<MyType> vec;

    std::auto_ptr<MyNestedType> nt1(new MyNestedType(2));
    std::auto_ptr<MyNestedType> nt2(new MyNestedType(5));
    MyType t1 = {nt1.get()};
    MyType t2 = {nt2.get()};

    vec.push_back(t1);
    vec.push_back(t2);

    std::for_each(vec.begin(), vec.end(), 
                  Caller<MyNestedType, &MyType::nested, &MyNestedType::func>());
    std::for_each(vec.begin(), vec.end(), 
                  Caller<MyNestedType, &MyType::nested, &MyNestedType::foo>());
}

Autres conseils

Pourquoi ne pas simplement utiliser une simple boucle?

for(vector<MyType>::iterator i = vec.begin(); i != vec.end(); ++i)
    i->nested->func();

Vous pouvez utiliser des expressions lambda ou boost :: foreach

FOREACH(MyType x, vec)
    x.nested->func();

Vous pouvez construire votre expression avec des liants et mem_funs, mais cela devenir très désordonné et confus! Il n'y a aucun avantage à mettre tout en une seule ligne std :: foreach.

Peut-être que vous pouvez ajouter func () dans MyType struct ():

void func(...) {
   nested->func(...);
}

De cette façon, vous n'aurez pas foncteur adaptateur séparé, mais une agrégation à l'intérieur de type d'emballage, à savoir tout à fait régulière technique POO.

Si vous voulez utiliser for_each vous avez besoin d'un foncteur.

struct CallMyFunc
{
    void operator()(MyType& obj)    {   obj.nested->func();}
};


std::for_each(vec.begin(), vec.end(), CallMyFunc());

Sinon j'utiliser le boost :: syntaxe FOREACH décrit par:

Dario: Appel fonctions membres de membres d'éléments d'un récipient avec for_each?

Oui, il est possible d'utiliser pour ce boost::bind, mais il devient malpropre. S'il vous plaît utiliser @ Boost de Dario for-each chemin, mais voici celui pour le <=> souci d'exhaustivité

std::for_each(vec.begin(), vec.end(), 
    boost::bind(&MyNestedType::func, boost::bind(&MyType::nested, _1)));

Quoi qu'il en soit, comme il arrive, nous ne même pas obtenir une belle uniligne avec ceci:)

Comment l'utilisation de Boost transform_iterator ?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top