Повысить 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 ответа

Решение

Вы только что столкнулись с ошибкой, которая мучает большую часть 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 и, таким образом, оценить до bool значение false,

Используя as_xpr, вы конвертируете C-строку в Xpressive объект, и, следовательно, ввести в право operator! от Xpressive пространство имен во внимание, и разрешение перегрузки включается соответствующим образом.

as_xpr помощник должен быть использован...

!as_xpr("sip:")
Другие вопросы по тегам