提升xpressive!操作员不工作

rus*_*sbi 2 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;
}`
Run Code Online (Sandbox Code Playgroud)

Mat*_* M. 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";
}
Run Code Online (Sandbox Code Playgroud)

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

关于Xpressive,大多数情况下它是有效的,因为你使用特殊的"标记",Xpressive类型实例像(_w)或因为病毒效应(例如"@"起作用,因为左边的表达>>Xpressive相关的).

你用的是:

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

它会起作用,因为由于Xpressive运营商的优先规则,右侧的论点被"污染"了.

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

`!"sip:"`
Run Code Online (Sandbox Code Playgroud)

并且由于"sip:"是类型char const[5],它只调用常规operator!,它将正确地推断出它所适用的表达式true,从而计算出boolfalse.

通过使用as_xpr,将转换为C-字符串转换成一个Xpressive对象,并由此带来的权利operator!Xpressive命名空间考虑,和重载决议踢适当.