Повысить 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
пространство имен во внимание, и разрешение перегрузки включается соответствующим образом.