2016-05-11 11 views
0

Ich habe eine Klasse mit einem einzigen Mitglied, das ist ein boost::variant von zwei Typen: ein vector von ganzen Zahlen und ein vector der enthaltenen Klassenobjekte (Letzteres muss offensichtlich sein getan mit Hilfe von recursive_wrapper). Der Code für die Klasse ist unterBoost :: Variante: seltsames Verhalten mit einem rekursiven Vektor Typ

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

#include <vector> 

class TestVariant 
{ 
public: 

    typedef boost::variant< std::vector<int>, boost::recursive_wrapper<std::vector<TestVariant> > > StorageType; 

    TestVariant(): 
     m_value{ std::vector<int>{} } 
    {} 

    TestVariant(const TestVariant& other): 
     m_value{ other.m_value } 
    {} 

    TestVariant& operator=(const TestVariant& other) 
    { 
     m_value = other.m_value; 

     return *this; 
    } 

    TestVariant(TestVariant&& other): 
     m_value{ std::move(other.m_value) } 
    {} 

    TestVariant& operator=(TestVariant&& other) 
    { 
     m_value = std::move(other.m_value); 

     return *this; 
    } 

    TestVariant(const std::vector<int>& value): 
     m_value{ value } 
    {} 

    TestVariant(std::vector<int>&& value): 
     m_value{ std::move(value) } 
    {} 

    TestVariant(const std::vector<TestVariant>& value): 
     m_value{ value } 
    {} 

    TestVariant(std::vector<TestVariant>&& value): 
     m_value{ std::move(value) } 
    {} 

private: 

    StorageType m_value; 
}; 

Wenn ich diese Klasse Versuchen Sie es mit durch eine vector von TestVariant zu schaffen und eine Instanz einer rekursiven Instanz von TestVariant emplacing wie unten

std::vector<TestVariant> v; 

v.emplace_back(std::vector<TestVariant>{ std::vector<TestVariant>{}, std::vector<int>{} }); // access violation! 

ich einen „Zugang erhalten Verletzung "Ausnahme unter MSVS 2013 und Boost ver 1.53 (Ich weiß, dies ist eine alte Version von Boost, aber ich bin organisatorisch beschränkt, um es im Moment zu verwenden). Derselbe Code auf Coliru funktioniert einwandfrei (siehe here).

Was noch seltsamer ist, dass, wenn ich die Reihenfolge der beiden Vektoren zu wechseln, alles in MSVS 2013

std::vector<TestVariant> v; 

v.emplace_back(std::vector<TestVariant>{std::vector<int>{}, std::vector<TestVariant>{} }); // works! 

Irgendwelche Ideen in Ordnung zu sein scheint? Ich habe versucht, dies für einen Tag jetzt zu lösen ...

+1

es wouldn Es ist nicht ungewöhnlich zu finden, dass es einen Bug gibt, ist MSVS2013 oder eine alte Version von Boost. Dies könnte eine gute Gelegenheit sein zu argumentieren, dass Ihre Organisation das Richtige tun und upgraden sollte? –

+0

@RichardHodges Ich könnte nicht mehr zustimmen, aber die Zahnräder drehen sich langsam und in der Zwischenzeit brauche ich einen Workaround ... –

+0

hilft Sehes Lösung? Ich würde anbieten, es zu versuchen, aber da es mich 2 Tage kostete, um vs2015 auf meinem Windows-Computer zu installieren, wage ich nicht, eine Seite-an-Seite-Installation zu versuchen. Wenn ich heute Code für Windows schreiben muss, benutze ich clang oder Cygwin. Ich traue Microsoft einfach nicht ... –

Antwort

0

Dies scheint in der Tat einer von vielen Bugs mit einheitlichen Initialisierung/Initialisierung Listen. Der Code ist „fein“ (in dem Sinne, dass das nicht UB auslöst)

Wenn es etwas ähnlich den Fehler, das ich lief in, Sie könnten versuchen, die typenames explizit angeben:

v.emplace_back(std::vector<TestVariant>{ 
    TestVariant(std::vector<TestVariant>{}), 
    TestVariant(std::vector<int>{}) }); 
+0

Das klappt leider nicht. –