提升表达力!操作员不工作

发布于 2024-09-18 22:20:09 字数 584 浏览 3 评论 0原文

我刚刚开始使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我不在是我 2024-09-25 22:20:09

您刚刚遇到了困扰大多数 DSEL 的错误。

问题是您希望调用一个特定的运算符,该运算符实际上是在您的特定语言中定义的。然而,该运算符已存在于 C++ 中,因此适用查找和重载解析的正常规则。

正确运算符的选择是通过 ADL(参数相关查找)完成的,这意味着至少应用该运算符的对象之一应该是 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] 类型,因此它只调用常规运算符! 将正确得出其应用的表达式为 true 的结论,从而计算出 boolfalse

通过使用 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:

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

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

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 are Xpressive type instances like (_w) or because of the viral effect (for example "@" works because the expression on the left of >> is Xpressive-related).

Were you to use:

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

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:

`!"sip:"`

And since "sip:" is of type char const[5], it just invokes the regular operator! which will rightly conclude that the expression to which it applies is true and thus evaluate to the bool value false.

By using as_xpr, you convert the C-string into an Xpressive object, and thus bring in the right operator! from the Xpressive namespace into consideration, and overload resolution kicks in appropriately.

我的奇迹 2024-09-25 22:20:09

必须使用 as_xpr 帮助器...

!as_xpr("sip:")

as_xpr helper must be used...

!as_xpr("sip:")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文