2016-08-15 72 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