boost::bind bei member



  • std::vector<std::string> strings; 
      strings.push_back("Boost"); 
      strings.push_back("C++"); 
      strings.push_back("Libraries"); 
    
      std::vector<int> sizes; 
    
      std::for_each(strings.begin(), strings.end(),
    	  boost::bind(&std::vector<int>::push_back, sizes, _1));
    
    error C2664: 'R boost::_mfi::mf1<R,T,A1>::operator ()<T>(const U &,A1) const' : cannot convert parameter 2 from 'std::basic_string<_Elem,_Traits,_Ax>' to 'const int &'
    

    Hallo, was ist falsch?
    Danke!



  • Wie dumm von mir. Zeile 6 muss natürlich vom Typ std::string sein. Wenn gerade schon einmal ein Thread auf ist, hat einer eine Idee, wie ich mit std::for_each nun die jeweilige std::string-Länge in "std::vector<int> sizes;" schreibe?

    Danke!



  • Ungetestet:

    std::for_each(strings.begin(), strings.end(),
          boost::bind(&std::vector<int>::push_back, boost::ref(sizes), 
                boost::bind(&std::string::length, _1)));
    

    Eleganter wäre aber wohl:

    transform(strings.begin(), strings.end(), back_inserter(sizes), bind(&string::length, _1));
    


  • Kóyaánasqatsi schrieb:

    Wie dumm von mir. Zeile 6 muss natürlich vom Typ std::string sein.

    Da liegt noch mehr im Argen: bind kopiert die Parameter. Du müsstest einen Referenz-Wrapper benutzen ( boost::ref(sizes) ). Außerdem wird demnächst (C++0x) push_back überladen, was dazu führt, dass &vector<string>::push_back sich auf mehr als eine Funktion bezieht und nicht mehr für "Template-Argument-Deduction" benutzt werden kann. back_inserter ist da die bessere Lösung. bind mit Elementfunktionszeiger wird man in C++0x wohl zugunsten von Lambdas weniger benutzen.

    Alternativ kann man einen transform_iterator benutzen:

    vector<int> sizes (tibeg, tiend);
    

    wobei tibeg und tiend transform_iteratoren sind, welche nur die Länge der Strings zurückgeben.


Log in to reply