2009-06-04 3 views
4

Ich habe Probleme herauszufinden mem_fun_ref. Ich muss zugeben, ich benutze normalerweise Funktoren für diese Art von Dingen, da sie für Geschwindigkeit und Profit inline sein können. Allerdings wird dieser Code kein Flaschenhals sein und deshalb wollte ich dieses Ding ausprobieren.mem_fun_ref Störung

Hier ist ein Beispiel, was ich tun möchte. Ich weiß, dass es andere Möglichkeiten gibt, es zu tun. Ich möchte nicht copy verwenden, ich möchte keine Bereichsgliedfunktionen verwenden, ich möchte kein back_inserter verwenden. Ich möchte speziell mem_fun_ref verwenden. Dies ist nur ein einfaches Beispiel, der reale Fall ist viel komplizierter. Das heißt, ich weiß wirklich nicht, warum das falsch ist, aber ich bin nicht vertraut mit mem_fun_ref oder mem_fun.

Hier ist, was ich arbeiten will:

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

Aber ich habe 3 Fehler:

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 macht ich denke, dass die Funktion einen Parameter nach Wert zu übernehmen muss. Aber natürlich ist es nicht möglich, in vector zu ändern, und es ist auch nicht möglich, es in meinem Code zu ändern. Gibt es eine einfache Änderung, um dies zum Laufen zu bringen? Ich brauche eine Lösung, die ein 1-Liner ist.

Antwort

4

Verwenden Sie einfach bind. Die mem_fun Versionen sind zu schwierig.

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

Ein anderer Weg, die nicht die Verwendung von ref erfordert, ist ein Zeiger auf den Vektor passieren modifiziert werden:

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

Dieser scheint nichts zu tun, als ich es versuchte! – rlbond

+0

Oh, es braucht boost :: ref. – rlbond

+0

so etwas? –

0

Ich weiß, dass Sie gesagt haben Sie wollen nicht Verwenden Sie back_inserter, wahrscheinlich, weil Sie einfach nur Beispielcode angegeben haben.

Für alle anderen Fragen, wie genau das tun, was Sie versuchen zu tun, und glücklich, es zu benutzen, verwenden Sie back_inserter:

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

Eigentlich ist ein besserer Weg b.insert (b.end(), a.begin(), a.end()); – rlbond

0

Das heißt, es gibt immer other_mem_fun, die ich bis gekocht vor Ich wusste von Boost. Das könnte passen.

+0

Gibt es einen Grund dafür, dass Sie Ihre vorherige Antwort nicht bearbeiten? –

+0

Weil es eigentlich eine Antwort auf die Frage ist, während meine andere Antwort eher eine Nebensache war. –

2

Dieses Problem wurde in "Exceptional C++ Style" von Herb Sutter, Seite 28-30 erläutert. Man kann wahrscheinlich nicht sicher einen Zeiger auf eine vector<int>::push_back-Methode erstellen, da man sich der genauen Signatur der Elementfunktion sicher sein muss, was selbst für vector<int>::push_back in der Standardbibliothek nicht offensichtlich ist. Dies liegt daran, (in der Standardbibliothek):

  1. Ein Mitglied Funktionssignatur mit Standardparametern könnte durch „zwei oder mehr Elementfunktion Signaturen mit gleichwertigem Verhalten ersetzt wird
  2. Ein Mitglied Funktionssignatur zusätzliche notleidenden Parameter haben könnte..

Am Ende geraten Herb Sutter, dass

  1. Verwenden mem_fun, nur nicht mit der Standardbibliothek
  2. Verwenden Zeigern auf Elementfunktionen, nur nicht mit der Standardbibliothek
Verwandte Themen