2017-09-08 4 views
2

Ich muss boost::variant Objekt erstellen und static_visitor verwenden. Leider brauche ich extra Parameter ...Zusätzliches Argument in operator() in boost :: static_visitor

Welche Lösung ist besser? Um dieses Objekt als Feld der Klasse zu haben, und wenn ich Besucher verwenden mag Ich habe Instanz erstellen:

class Visitor : public boost::static_visitor<> 
{ 
public: 
    Visitor(int extra): extra{extra} {} 
    void operator()(const T1&) { /* ... */} 
    void operator()(const T2&) { /* ... */} 

private: 
    int extra; 
}; 

und Besucher Objekt jedes Mal, wenn ich will, es benutzen:

Visitor visitor(x); 
boost::apply_visitor(visitor, t); 

oder boost :: bind verwenden und Besucher einmal erstellen und boost::bind verwenden?

class Visitor : public boost::static_visitor<> 
{ 
public: 
    void operator()(const T1&, int extra) { /* ... */ } 
    void operator()(const T2&, int extra) { /* ... */ } 
}; 

Verbrauch:

auto visitor = std::bind(SctpManager::Visitor(), std::placeholders::_1, extra); 
boost::apply_visitor(visitor, t); 

Was ist besser (schneller, elegante) Lösung?

Oder gibt es bessere Lösungen?

Antwort

1

Es gibt keine im Wesentlichen eleganter Weise. Sie können Lambdas verwenden (wenn Ihre Compiler/Boost-Version modern genug ist).

Die "low-tech" Option ist es, eine Struktur zu verwenden, die den Zustand (3. Beispiel) gilt:

Live On Coliru

#include <boost/variant.hpp> 
#include <iostream> 

struct T1{}; 
struct T2{}; 

struct Visitor : boost::static_visitor<> 
{ 
    void operator()(T1 const&, int extra) const { std::cout << __PRETTY_FUNCTION__ << " extra:" << extra << "\n"; } 
    void operator()(T2 const&, int extra) const { std::cout << __PRETTY_FUNCTION__ << " extra:" << extra << "\n"; } 
}; 

int main() { 
    boost::variant<T1, T2> tests[] = { T1{}, T2{} }; 

    { 
     Visitor vis; 
     for (auto v: tests) 
      apply_visitor([=](auto const& v) { vis(v, 42); }, v); 
    } 

    { 
     auto vis = [vis=Visitor{}](auto const& v) { vis(v, 1); }; 
     for (auto v: tests) 
      apply_visitor(vis, v); 
    } 


    { 
     struct { 
      using result_type = void; 
      int extra; 
      void operator()(T1 const&) const { std::cout << __PRETTY_FUNCTION__ << " extra:" << extra << "\n"; } 
      void operator()(T2 const&) const { std::cout << __PRETTY_FUNCTION__ << " extra:" << extra << "\n"; } 
     } vis { 99 }; 

     for (auto v: tests) 
      apply_visitor(vis, v); 
    } 
} 

Drucke

void Visitor::operator()(const T1&, int) const extra:42 
void Visitor::operator()(const T2&, int) const extra:42 
void Visitor::operator()(const T1&, int) const extra:1 
void Visitor::operator()(const T2&, int) const extra:1 
void main()::<unnamed struct>::operator()(const T1&) const extra:99 
void main()::<unnamed struct>::operator()(const T2&) const extra:99 
Verwandte Themen