提升表达力!操作员不工作
我刚刚开始使用 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;
}`
I just started using Boost::xpressive and find it an excellent library... I went through the documentation and tried to use the ! operator (zero or one) but it doesn't compile (VS2008).
I want to match a sip address which may or may not start with "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;
}`
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您刚刚遇到了困扰大多数 DSEL 的错误。
问题是您希望调用一个特定的运算符,该运算符实际上是在您的特定语言中定义的。然而,该运算符已存在于 C++ 中,因此适用查找和重载解析的正常规则。
正确运算符的选择是通过 ADL(参数相关查找)完成的,这意味着至少应用该运算符的对象之一应该是 DSEL 本身的一部分。
例如,考虑这个简单的代码片段:
因为表达式是从左到右计算的,所以 dsel::MyObject 的存在是病毒式的,即 dsel 将在这里传播。
关于
Xpressive
,大多数时候它之所以有效,是因为您使用了Xpressive
类型实例(如 (_w
))的特殊“标记”,或者因为病毒效应(例如,“@”之所以有效,是因为>>
左侧的表达式与Xpressive
相关)。如果您使用:
它会起作用,因为由于运算符的优先规则,右侧参数被
Xpressive
“污染”。然而这里
operator!
具有最高优先级之一。因此,它的范围仅限于:并且由于
"sip:"
是char const[5]
类型,因此它只调用常规运算符! 将正确得出其应用的表达式为
true
的结论,从而计算出bool
值false
。通过使用
as_xpr
,您可以将 C 字符串转换为Xpressive
对象,从而从Xpressive 中引入正确的
命名空间被考虑在内,并且重载解析会适当地启动。运算符!
You just encountered a bug that plagues most of the DSEL.
The issue is that you want a specific operator to be called, the one actually defined in your specific languages. However this operator already exist in C++, and therefore the normal rules of Lookup and Overload resolution apply.
The selection of the right operator is done with ADL (Argument Dependent Lookup), which means that at least one of the objects on which the operator apply should be part of the DSEL itself.
For example, consider this simple code snippet:
Because the expression is evaluated from left to right, the presence of
dsel::MyObject
is viral, ie the dsel will here be propagated.Regarding
Xpressive
, most of the times it works because you use special "markers" that areXpressive
type instances like (_w
) or because of the viral effect (for example "@" works because the expression on the left of>>
isXpressive
-related).Were you to use:
It would work, because the right hand-side argument is "contaminated" by
Xpressive
thanks to the precedence rules of the operators.However here
operator!
has one of the highest precedence. At such, its scope is restricted to:And since
"sip:"
is of typechar const[5]
, it just invokes the regularoperator!
which will rightly conclude that the expression to which it applies istrue
and thus evaluate to thebool
valuefalse
.By using
as_xpr
, you convert the C-string into anXpressive
object, and thus bring in the rightoperator!
from theXpressive
namespace into consideration, and overload resolution kicks in appropriately.必须使用
as_xpr
帮助器...as_xpr
helper must be used...