提升xpressive!操作员不工作

时间:2010-09-14 11:54:48

标签: c++ regex boost boost-xpressive

我刚开始使用Boost :: xpressive并发现它是一个很棒的库...我浏览了文档并尝试使用!运算符(零或一)但它不编译(VS2008)。

我想匹配一个SIP地址,该地址可能是也可能不是以“sip:”

开头
#include <iostream>
#include <boost/xpressive/xpressive.hpp>

using namespace boost::xpressive;
using namespace std;
int main()
{


    sregex re = !"sip:" >> *(_w | '.') >> '@' >> *(_w | '.');

    smatch what;
    for(;;)
    {
        string input;
        cin >> input;

        if(regex_match(input, what, re))
        {
            cout << "match!\n";
        }
    }

    return 0;
}`

2 个答案:

答案 0 :(得分:8)

你刚刚遇到了一个困扰大部分DSEL的错误。

问题是您希望调用特定的运算符,即在您的特定语言中实际定义的运算符。但是,此运算符已存在于C ++中,因此适用于查找和重载分辨率的常规规则。

右运算符的选择是通过ADL(Argument Dependent Lookup)完成的,这意味着运算符所适用的对象中至少有一个应该是DSEL本身的一部分。

例如,请考虑以下简单的代码段:

namespace dsel
{
  class MyObject;
  class MyStream;
  MyStream operator<<(std::ostream&, MyObject);
}

int main(int, char*[])
{
  std::cout << MyObject() << "other things here";
}

因为表达式是从左到右评估的,dsel::MyObject的存在是病毒式的,即dsel将在这里传播。

关于Xpressive,大部分时间都可以使用,因为您使用Xpressive类型实例(_w)的特殊“标记”或因为病毒效应(例如“ @“有效,因为>>左侧的表达式是Xpressive - 相关的。)

你要使用:

sregex re = "sip:" >> *(_w | '.') >> '@' >> *(_w | '.');
            ^^^^^^ ~~ ^^^^^^^^^^^
            Regular    Xpressive

这样可行,因为由于操作符的优先级规则,右侧参数被Xpressive“污染”。

但是operator!有一个最高优先级。在这种情况下,其范围仅限于:

`!"sip:"`

由于"sip:"的类型为char const[5],因此它只会调用常规operator!,这将正确地推断出它应用的表达式为true,从而评估为boolfalse

通过使用as_xpr,您可以将C字符串转换为Xpressive对象,从而将operator!命名空间中的右Xpressive引入考虑范围,并超载决议适当地开始。

答案 1 :(得分:1)

必须使用

as_xpr帮助...

!as_xpr("sip:")