2011-11-29 71 views
1

看来的boost :: xpressive中不提供new运营商的评价懒洋洋的版本,所以这个语义动作不会编译:如何在boost :: xpressive语义动作中使用“new”运算符?

using namespace boost::xpressive ; 
std::vector<int*> vec ; 

// Match any integer and capture into s1. 
// Then use a semantic action to push it onto vec. 
sregex num = (s1= +digit)[ ref(vec)->*push_back(new as<int>(s1)) ] ; 

是否有在语义动作使用new运算符的构建?例如,boost :: phoenix为lambda提供了new_函数。 xpressive是否提供了类似的语义操作?

回答

1

这是迄今为止我所得出的最好结果。该代码定义了一个函数,该函数允许您使用语法new_<T>::with(...)作为等效于new T(...)的语义操作。该功能在lazy function exampleboost xpressive user guide之后建模。 (下面仅将片段支持最多2个参数的构造函数,而是加入了更多的复制/粘贴的问题。)

using namespace boost::xpressive ; 

template <typename _ObjectType> 
struct new_impl 
{ 
    typedef _ObjectType* result_type; 

    _ObjectType* operator()() const 
    { 
     return new _ObjectType() ; 
    } 

    template<typename _T0> 
    _ObjectType* operator()(_T0 const &a0) const 
    { 
     return new _ObjectType(a0) ; 
    } 

    template<typename _T0, typename _T1> 
    _ObjectType* operator()(_T0 const &a0, _T1 const &a1) const 
    { 
     return new _ObjectType(a0, a1) ; 
    } 
}; 

template <typename _ObjectType> 
struct new_ 
{ 
    static const typename function<new_impl<_ObjectType> >::type with ; 
}; 
template <typename _ObjectType> 
const typename function<new_impl<_ObjectType> >::type new_<_ObjectType>::with = {{}}; 

这里,它是在行动:

int main() 
{ 
    std::vector<int*> vec ; 

    // Matches an integer, with a semantic action to push it onto vec 
    sregex num = (s1= +digit) 
       [ ref(vec)->*push_back(new_<int>::with(as<int>(s1))) ] ; 

    // Space-delimited list of nums 
    sregex num_list = num >> *(' ' >> num) ; 

    std::string str = "8 9 10 11" ; 
    if (regex_match(str, num_list)) 
    { 
     std::cout << "Found an int list: " ; 
     BOOST_FOREACH(int* p, vec) 
     { 
      std::cout << *p << ' ' ; 
     } 
    } 
    else 
    { 
     std::cout << "Didn't find an int list." ; 
    } 

    return 0 ; 
} 

输出:

Found an int list: 8 9 10 11 

要提高上述代码的一般性,最好将参数类型更改为使用boost::add_reference<>boost::add_const<>,但您明白了。