boost::spirit::qi是一个用于解析字符串的库,可以用于解析字符串并构造对象。在解析的过程中,有时候需要构造语法树,这个时候通常可以采用phx::new_或者phx::construct来构造裸指针或对象。但是在实际的应用当中,有时候会希望通过如std::shared_ptr这样的智能指针来管理对象的生命周期,但是在boost::phoenix当中并没有提供make_shared这样的函数对象。
基于stackoverflow上的回答可以构造一个make_shared_的函数对象,用于在boost::spirit::qi的语法规则当中延迟构造std::shared_ptr对象。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | namespace boost::phoenix {template <typename T>
 struct make_shared_f {
 template <typename... A>
 struct result {
 typedef std::shared_ptr<T> type;
 };
 
 template <typename... A>
 typename result<A...>::type operator()(A&&... a) const {
 return std::make_shared<T>(std::forward<A>(a)...);
 }
 };
 template <typename T>
 using make_shared_ = function<make_shared_f<T>>;
 }
 
 | 
在使用的时候可以如下构造创建std::shared_ptr对象的action:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | namespace qi = boost::spirit::qi;namespace phx = boost::phoenix;
 
 using phx::make_shared_;
 using qi::_1;
 using qi::_val;
 
 ...
 
 expr = term[_val = _1] >>
 *(('+' >> term[_val = make_shared_<AddNode>()(_val, _1)]) |
 ('-' >> term[_val = make_shared_<SubNode>()(_val, _1)]));
 
 |