2016-08-15 1 views
3

Le code suivant crashes GCC et ne parvient pas à compiler avec Clang. Qu'est ce qui ne va pas avec ça?Héritage de boost :: variant et templatifisé AST

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


template<class Node> 
struct wrapper1; 
template<class Node> 
struct wrapper2; 

struct ast_node; 
using ast_node_base = boost::variant<boost::recursive_wrapper<wrapper1<ast_node>>, boost::recursive_wrapper<wrapper2<ast_node>>>; 

struct ast_node : ast_node_base 
{ 
    using ast_node_base::ast_node_base; 
}; 

template<class Node> 
struct wrapper1 
{ 
    std::array<Node, 1> children; 
}; 

template<class Node> 
struct wrapper2 
{ 
    std::array<Node, 2> children; 
}; 


int main() 
{ 
    ast_node node; 
    std::cout << "done\n"; 
} 

Répondre

2

Vous obtenez une récursion infinie dans le constructeur.

Le premier membre de variante contient lui-même un agrégat de 1 nœud. Par défaut, le ast_node construit initialisera récursivement wrapper1, ce qui se répercute lorsque la pile déborde.

solution la plus simple:

Live On Coliru

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

template <class Node> struct wrapper1; 
template <class Node> struct wrapper2; 

struct nil {}; 
struct ast_node; 
using ast_node_base = boost::variant<nil, boost::recursive_wrapper<wrapper1<ast_node> >, boost::recursive_wrapper<wrapper2<ast_node> > >; 

struct ast_node : ast_node_base { 
    using ast_node_base::ast_node_base; 
}; 

template <class Node> struct wrapper1 { std::array<Node, 1> children; }; 
template <class Node> struct wrapper2 { std::array<Node, 2> children; }; 

int main() { 
    ast_node node; 
    std::cout << "done\n"; 
} 
+0

clang ++ [qu'il aime] (http://coliru.stacked-crooked.com/a/26ff6c04b3597b01) trop – sehe