2010-03-10 19 views
9

Ich habe einen Vektor Zeiger. Ich möchte eine Funktion für jedes Element aufrufen, aber diese Funktion nimmt eine Referenz. Gibt es eine einfache Möglichkeit, die Elemente zu dereferenzieren?Verwendung for_each und boost :: bind mit einem Vektor von Zeigern

Beispiel:

MyClass::ReferenceFn(Element & e) { ... } 

MyClass::PointerFn(Element * e) { ... } 

MyClass::Function() 
{ 
    std::vector< Element * > elements; 
    // add some elements... 

    // This works, as the argument is a pointer type 
    std::for_each(elements.begin(), elements.end(), 
        boost::bind(&MyClass::PointerFn, boost::ref(*this), _1)); 

    // This fails (compiler error), as the argument is a reference type 
    std::for_each(elements.begin(), elements.end(), 
        boost::bind(&MyClass::ReferenceFn, boost::ref(*this), _1)); 
} 

Ich könnte ein schmutziges kleines Wrapper erstellen, die einen Zeiger nimmt, aber ich dachte, es einen besseren Weg sein?

+0

Gibt es einen Grund, warum Sie 'boost :: ref (* this)' verwenden? Ich benutze einfach: boost :: bind (& MyClass :: ReferenceFn, this, _1) und es funktioniert gut. –

Antwort

15

Sie könnten boost::indirect_iterator verwenden:

std::for_each(boost::make_indirect_iterator(elements.begin()), 
       boost::make_indirect_iterator(elements.end()), 
       boost::bind(&MyClass::ReferenceFn, boost::ref(*this), _1)); 

Das wird dereferenzieren die angepasst Iterator zweimal in seiner operator*.

+4

+1, obwohl ich für diesen Fall lieber 'BOOST_FOREACH (Element * e, Elemente) this-> ReferenceFn (* e);'. C++ kann als funktionale Sprache verwendet werden, aber nicht als eine * prägnante * funktionale Sprache ... –

+0

Und das Python wäre 'für e in elements: self.ReferenceFn (e)'. Es ist herzzerreißend. –

+4

Für C++ 0x wird es 'für (auto * e: elements) ReferenceFn (* e);'. Süße :) –

3

Es sieht so aus, als könnten Sie auch die Boost.Lambda Bibliothek verwenden.

// Appears to compile with boost::lambda::bind 
    using namespace boost::lambda; 
    std::for_each(elements.begin(), elements.end(), 
        bind(&MyClass::ReferenceFn, boost::ref(*this), *_1)); 

Aber ich stimme mit den commen über BOOST_FOREACH bevorzugen. Der for_each "Algorithmus" macht praktisch nichts Sinnvolles, und was er tut, kann range-based for-loop mit einem viel geringeren Aufwand für Sie tun.

Verwandte Themen