似乎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为lambdas提供new_
函数。 xpressive是否为语义动作提供了类似的东西?
答案 0 :(得分:1)
这是迄今为止我提出的最好的。此代码定义了一个函数,允许您使用语法new_<T>::with(...)
作为等同于new T(...)
的语义操作。该函数以lazy function example中的boost 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<>
,但您明白了。