2016-08-15 65 views
3

以下代码crashes GCC并且无法使用Clang进行编译。它出什么问题了?继承boost :: variant和templatized 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"; 
} 

回答

2

您在构造函数中获得无限递归。

第一个变体成员本身包含1个节点的聚合。因此默认构建的ast_node将递归地初始化wrapper1,当堆栈溢出时,该值为底部。

简单的解决办法:

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

铛++ [喜欢它](http://coliru.stacked-crooked.com/a/26ff6c04b3597b01)太 – sehe