2010-12-09 6 views
0

Ich habe eine Vorlage wie folgt aussehen:Gang in einer Funktion Rückgabewert zu erhalten oder Werte

struct add_node_value_visitor : boost::static_visitor<> 
{ 
    add_node_value_visitor(){} 

    template <typename T> 
    void operator() (const T& value) const 
    { 
     boost::lexical_cast<std::string, T>(value); 
    } 

}; 

Das Problem, das ich habe, ist, dass der Besucher im Inneren ein Iterieren for-Schleife über eine Reihe von Werten verwendet wird, und Die resultierende Folge von Werten muss eine Zeichenkette sein. Zur Zeit würde dies eine Menge separater Zeichenketten ergeben, was nicht das ist, was ich möchte. Um dieses Problem zu lösen, dachte ich, ich würde einen Funktionszeiger auf den ctor dieser Struktur setzen Ich kann eine Funktion übergeben, um die resultierende Zeichenfolge jeder Schleifeniteration zu verketten und eine Zeichenfolge zu erstellen. Dann, wenn ich diese Struktur verwenden möchte, wo ich keine Verkettung brauche, kann ich das immer noch tun. Die Frage ist, ob ich einen Funktionszeiger verwenden soll oder ist das möglich mit etwas wie boost :: lambda?

Oder wäre boost :: function einfacher zu bedienen?

+0

Ist meine Frage unverständlich oder weiß niemand? –

+3

Es ist ziemlich früh an einigen Stellen ... zu dieser Zeit werden die Menschen in Amerika noch schlafen, und einige Leute in Europa (wie ich) werden immer noch auf einen Becher Kaffee zum Aufwachen hinkriechen. Zeit für Kaffee! –

Antwort

1

So ähnlich?

struct add_node_value_visitor : public boost::static_visitor<> 
{ 
public: 
    typedef std::function<void(const std::string&)> concat_func_t; 

    add_node_value_visitor(const concat_func_t& concat) : concat_(concat){} 

    template <typename T> 
    void operator() (const T& value) const 
    { 
     concat_(boost::lexical_cast<std::string, T>(value)); 
    } 

private: 
    concat_func_t concat_; 
}; 
0

Warum nicht die Verkettung an Ort und Stelle durchführen?

struct add_node_value_visitor : boost::static_visitor<> 
{ 
    std::ostringstream st; 
    template <typename T> 
    void operator() (const T& value) { 
     // change concatenation logic here if required (separators...) 
     st << value; 
    } 
    std::string const & str() const { 
     return st.str(); 
    } 
}; 
+0

Ich könnte diese Funktion an einem Ort verwenden, an dem keine Concat benötigt wird, also reduziert das meine Flexibilität, denke ich. –

+0

Wird die zusätzliche Komplexität (Code, Ort des Anrufs) kompensieren? Sie müssen zwei verschiedene Funktoren schreiben, die 10 Codezeilen enthalten, von denen die meisten eine einfache Kesselbeschriftung sind, im Gegensatz zu einer zusätzlichen Komplexität (Sie müssen der Klasse den Funktionszeiger/concat funktor hinzufügen und die zusätzliche Funktion/den Funktor erstellen. Ist das einfacher, weniger fehleranfällig, was erreichen Sie wirklich? –

0

Vielleicht wäre ein allgemeinerer Besucher in Ordnung, der es dem Anrufer überlassen würde, was mit den String-Darstellungen zu tun ist.

#include <boost/variant.hpp> 
#include <boost/lexical_cast.hpp> 
#include <string> 
#include <vector> 
#include <iostream> 

struct to_string : boost::static_visitor<std::string> 
{ 

    template <typename T> 
    std::string operator() (const T& value) const 
    { 
     return boost::lexical_cast<std::string, T>(value); 
    } 

}; 

int main() 
{ 
    std::vector<boost::variant<int, double> > vec; 
    vec.push_back(42); 
    vec.push_back(3.14); 
    std::string result; 
    for (size_t i = 0; i != vec.size(); ++i) { 
     result += boost::apply_visitor(to_string(), vec[i]) + ' '; 
    } 
    std::cout << result; 
} 
Verwandte Themen