Question

Je ne parviens pas à déterminer mem_fun_ref. Je dois admettre que, je l'habitude d'utiliser foncteurs pour ce genre de chose, car ils peuvent être inline pour la vitesse et le profit. Cependant, ce code ne va pas être un goulot d'étranglement et donc je voulais essayer cette chose.

Voici un exemple de ce que je veux faire. Je sais qu'il ya d'autres façons de le faire. Je ne veux pas utiliser copy, je ne veux pas utiliser les fonctions membres de gamme, je ne veux pas utiliser un back_inserter. Je veux spécifiquement utiliser mem_fun_ref. Ceci est juste un exemple simple, le cas réel est beaucoup plus compliqué. Cela dit, je ne sais vraiment pas pourquoi cela est faux, mais je ne suis pas familier avec mem_fun_ref ou mem_fun.

Voici ce que je veux travailler:

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

Mais je reçois 3 erreurs:

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 me fait penser que la fonction doit prendre un paramètre par valeur. Mais bien sûr, ce n'est pas possible de changer vector, et il est impossible de le changer soit dans mon code. Y at-il un simple changement pour que cela fonctionne? J'ai besoin d'une solution qui est un 1-liner.

Était-ce utile?

La solution

Il suffit d'utiliser bind. Les versions mem_fun sont trop difficiles.

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

Une autre façon qui ne nécessite pas l'utilisation de ref est de passer un pointeur vers le vecteur à modifier:

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

Autres conseils

Ce problème a été expliqué dans "Exceptional C ++ Style" par Herb Sutter, à la page 28-30. Un créer ne peut probablement pas en toute sécurité un pointeur vers une méthode de vector<int>::push_back car il faut être sûr de la signature exacte de la fonction de membre, qui ne peut être évidente même pour vector<int>::push_back dans la bibliothèque standard. En effet, (dans la bibliothèque standard):

  1. Une signature de fonction membre avec les paramètres par défaut peut être remplacé par « deux ou plusieurs signatures fonction des membres ayant un comportement équivalent.
  2. Une signature de fonction membre peut avoir des paramètres supplémentaires en défaut.

En fin de compte, Herb Sutter a informé que

  1. Utilisez mem_fun, mais pas avec la bibliothèque standard
  2. Utilisez Pointeurs de fonctions membres, mais pas avec la bibliothèque standard

Je sais que vous avez dit que vous ne voulez pas utiliser back_inserter, probablement parce que vous avez donné tout code exemple simplifié.

Pour quelqu'un d'autre se demander comment faire exactement ce que vous essayez de faire, et heureux de l'utiliser, utilisez back_inserter:

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

Cela dit, il y a toujours other_mem_fun , que je cuisinais avant que je connaissais coup de pouce. Cela pourrait s'adapter.

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