2016-03-31 8 views
1

Ich habe eine von boost::variant Objekt, und ich versuche, eine boost::static_visitor erstellen, die ein Element im Array besucht, einen Verweis auf etwas in jedem der Variante Mitgliedstypen. Das ist ein Mund voll, also hier ist ein Code-Snippet imitiert meine Implementierung:boost :: variant Besucherrückgabe Fehler (am meisten ärgerlichen Parse?)

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

struct SomeType {}; 

struct A { 
    SomeType something; 
    SomeType& someMethod() { return something; } 
}; 

struct B { 
    SomeType something; 
    SomeType& someMethod() { return something; } 
}; 

struct C { 
    SomeType something; 
    SomeType& someMethod() { return something; } 
}; 

typedef boost::variant<A, B, C> MyVariant; 

class SomeVisitor : public boost::static_visitor<> { 
public: 
    template<typename T> 
    SomeType& operator()(T& operand) const { 
    return operand.someMethod(); 
    } 
}; 

class MyVariants { 
public: 
    SomeType* getSomething(unsigned index); 

private: 
    static const size_t count = 100; 
    std::array<MyVariant, count> variants_; 
}; 

SomeType* MyVariants::getSomething(unsigned index) { 
    if(index < count) { 
    MyVariant& variant = variants_[index]; 
    SomeType& something = boost::apply_visitor(SomeVisitor(), variant); 
    return &something; 
    } 
    else { 
    return nullptr; 
    } 
} 

Dieser Code-Schnipsel kompiliert mit Klirren 3.6.2, aber gcc 5.3.1 spuckt die folgenden (gefolgt von ein paar Dutzend Fehler aus den Boost-Variante headers

)
test.cpp:43:47: error: invalid initialization of non-const reference of type 'SomeType&' from an rvalue of type 'boost::static_visitor<>::result_type {aka void}' 
    SomeType& something = boost::apply_visitor(SomeVisitor(), variant); 

Alle Fehler scheinen dasselbe zu sagen - der Rückgabetyp des Besuchers void ist, und ich kann das nicht binden an eine SomeType&. Ich glaube nicht, dass es Syntaxfehler mit meiner Implementierung von SomeVisitor gibt, da dies mit clang gut funktioniert.

This question und this question zeigen ähnliche Fehler, die von einem boost::static_visitor erzeugt wurden, und beide wurden von C++ 's am meisten ärgerlichen Parse erklärt. In diesen beiden Fragen, war die Frage so etwas wie diese (mit Typen aus meinem Schnipsel oben):

MyVariant variant(A()); 
SomeType& something = boost::apply_visitor(SomeVisitor(), variant); 

In diesem Zusammenhang kann ich verstehen, wie die drängendsten Parse gilt. MyVariant variant(A()); könnte für den Compiler mehrdeutig sein. Ich weiß allerdings nicht, wie das auf mein Snippet zutrifft, denn MyVariant& variant = variants_[index] scheint ziemlich explizit zu sein. Ich weiß nicht, ob diese Fragen überhaupt mit meinen Problemen zu tun haben.

Jede Beratung/Hilfe würde als Antwort bereitgestellt

+2

Sie haben den Rückgabetyp in static_visitor der Vorlage Argumentliste angeben. Bleibt es leer, teilt es dem Compiler mit, dass der Funktor void zurückgibt. –

+0

Danke! Das war genau das Problem. Ich habe vor ein paar Wochen einen 'boost :: static_visitor' mit einem Rückgabewert gemacht (mit der richtigen Syntax), also bin ich doppelt peinlich –

+0

Wir haben es alle geschafft. Beachten Sie, dass Sie in späteren Versionen von Boost mit C++ 14 keinen statischen Besucher benötigen. Ein Lambda mit 'Auto &' Argument Typ wird ausreichen. –

Antwort

1

Kommentar geschätzt werden:

Sie haben den Rückgabetyp in static_visitor der Vorlage Argumentliste angeben. Bleibt es leer, teilt es dem Compiler mit, dass der Funktor void zurückgibt.

class SomeVisitor : public boost::static_visitor<SomeType&> { 
public: 
    template<typename T> 
    SomeType& operator()(T& operand) const { 
    return operand.someMethod(); 
    } 
}; 

Alternativ kann in späteren Versionen von Boost mit C++ 14:

auto& something = boost::apply_visitor([](auto& x) { return x.someMethod(); }, 
             variant); 
Verwandte Themen