2016-03-25 18 views
4
implementiert

Ich verstehe, dass boost::variant so etwas wie implementiert wirdWie Operator << mit boost :: Variante ist

template <typename... Vs> 
struct variant { 
    std::aligned_union<Vs...>::type buffer; 
    .... 
}; 

Wie können wir ein operator<< für eine Struktur wie diese machen, dass die Abgüsse den Typ in der gespeicherten Abdrücken Puffer und übergibt das an operator<< für cout? Dazu müssten wir den Typ des im Puffer gespeicherten Elements wissen, oder? Gibt es eine Möglichkeit, das zu wissen?

Auch ich bin auf der Suche nach einer Erklärung für eine solche Implementierung, wenn eine existiert. Nicht nur dass es existiert und wie ich es benutzen kann.

Antwort

5

Boost hat eine apply_visitor-Funktion, die ein generisches Funktionsobjekt übernimmt und den Typ der Variante in es übergibt. So operator<< Umsetzung ist so einfach wie:

template <class... Ts> 
std::ostream& operator<<(std::ostream& os, boost::variant<Ts...> const& var) { 
    return boost::apply_visitor(ostream_visitor{os}, var); 
} 

mit:

struct ostream_visitor : boost::static_visitor<std::ostream&> 
{ 
    std::ostream& os; 

    template <class T> 
    std::ostream& operator()(T const& val) { 
     return os << val; 
    } 
}; 

Oder einfach:

template <class... Ts> 
std::ostream& operator<<(std::ostream& os, boost::variant<Ts...> const& var) { 
    return boost::apply_visitor([&os](const auto& val) -> std::ostream& { 
     return os << val; 
    }, var); 
} 

Sie können einige andere Beispiele in der tutorial sehen.

+0

Vielen Dank für Ihre Antwort! Könntest du es bitte etwas weiter erklären? Ich habe nicht wirklich verstanden, was vor sich geht ... Woher weiß der 'ostream_visitor', um welchen Typ es sich handelt? Das 'T' in der Funktion scheint nur in den Typ 'boost :: variant ' zu passen. – Curious

+0

@Curious Nein, es ist definitiv nicht. Lesen Sie das Tutorial, es ist alles ziemlich gut darin erklärt. – Barry

+0

Danke. Ich habe deine Antwort erneuert. Ich werde es lesen. Aber im Funktor gibst du einfach den Variantentyp rein? Wie weiß Boost, welcher Typ des Objekts in der Variablen enthalten ist? Ich wollte die Dinge mehr in die Richtung fragen, wie Boost dieses implementiert – Curious