2016-05-11 1 views
0

J'ai une classe avec un seul membre qui est un boost::variant de deux types: un vector d'entiers et un vector des objets de classe contenant (ce dernier doit évidemment être fait avec l'aide de recursive_wrapper). Le code de la classe est inférieure àboost :: variant: comportement étrange avec un type de vecteur récursif

#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; 
}; 

Quand j'essayer d'utiliser cette classe en créant une vector de TestVariant et: Montage d'une instance d'une instance récursive de TestVariant comme ci-dessous

std::vector<TestVariant> v; 

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

Je reçois un « accès violation "exception sous MSVS 2013 et Boost ver 1.53 (je sais que c'est une ancienne version de Boost, mais je suis contraint d'utiliser l'organisation pour le moment). Le même code sur coliru fonctionne bien (voir here).

Ce qui est encore plus étrange est que si je passe l'ordre des deux vecteurs, tout semble être bien dans MSVS 2013

std::vector<TestVariant> v; 

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

Toutes les idées? J'ai essayé de résoudre ceci pendant un jour maintenant ...

+1

il wouldn Il ne sera pas inhabituel de trouver qu'il y a un bug MSVS2013 ou une ancienne version de boost. Cela pourrait être une bonne occasion de faire valoir que votre organisation devrait faire la bonne chose et améliorer? –

+0

@RichardHodges Je ne pouvais pas être plus d'accord, mais les rouages ​​tournent lentement et, en attendant, j'ai besoin d'une solution de contournement ... –

+0

est-ce que la solution de sehe aide? Je proposerais de l'essayer mais comme ça m'a coûté 2 jours pour avoir installé vs2015 sur mon ordinateur Windows je n'ose pas essayer une installation côte à côte. Ces jours-ci, si j'ai besoin d'écrire du code pour Windows, j'utilise clang ou Cygwin. Je ne fais pas confiance à Microsoft ... –

Répondre

0

Cela semble en effet être l'un des nombreux bogues avec des listes d'initialisation/initialisation uniformes. Le code est « bien » (dans le sens où cela ne déclenche pas UB)

Si elle est quelque chose de semblable aux insectes je suis tombé, vous pouvez essayer de préciser les typenames explicitement:

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

Cela ne fonctionne malheureusement pas. –