c++函数式编程( boost::phoenix && boost::spirit)测试指针占位符中的空指针
因此,我有以下精神业力规则主体:
base_rule =
eps(_r1 != 0) [ // _r1 is a pointer_typed placeholder
eps
]
;
这会导致来自 g++ 的相当长的错误消息,该消息(有帮助地)以以下内容结尾:
/opt/dev_64_swat/Boost/include/boost/spirit/home/phoenix/operator/comparison.hpp
:37:5: error: ISO C++ forbids comparison between pointer and integer
[-fpermissive]
This is valid c++:
struct zebra{};
int main()
{
zebra * x;
if( x == 0);
}
Ithought to try boost::phoenix::static_cast_<_r1_type * >(0)
以及将 _r1_type
转换为整数(是的,这是错误的,这只是一个实验)。
问题:
如何使用spirit eps 构造对占位符执行指针测试,以防止点为零时规则体评估?
与所有“C++ 函数式编程库的使用”问题一样,我希望答案会让我感觉自己像个傻瓜。
答案
Ildjam 的观点直接回答了我的问题。我的问题有两个问题;上面有一个间接的问题。这与 PEG 中的条件有关。我想要表达的内容应该这样写:
rule = ( eps(_r) << ( /* grammar for when pointer is not null */ ) )
| eps // otherwise dont do anything.
;
我使用语义动作主体(在 [] 块中指定)来表达语法的条件部分。奇怪的是,虽然我以前写过条件PEG语法,但我只是犯了一个错误,这导致了第二类问题。
因此, eps(_r1) 可以解决问题,第二种编译问题与问题无关。
So, I have the following spirit karma rule body:
base_rule =
eps(_r1 != 0) [ // _r1 is a pointer_typed placeholder
eps
]
;
which leads to a rather long error message from g++ which (helpfully) ends with :
/opt/dev_64_swat/Boost/include/boost/spirit/home/phoenix/operator/comparison.hpp
:37:5: error: ISO C++ forbids comparison between pointer and integer
[-fpermissive]
This is valid c++:
struct zebra{};
int main()
{
zebra * x;
if( x == 0);
}
I thought to try boost::phoenix::static_cast_<_r1_type *>(0)
as well as converting _r1_type
to a integer (yes that is WRONG, it was just an experiment).
The question:
How can I use a spirit eps construct to perform a pointer test on a placeholder to prevent rule body evaluation when the point is zero ?
As with all "C++ functional programming library usage" questions I expect the answer to leave me feeling like a dimwit.
The Answer
Ildjam's point directly answers my question. There were two issues with my problem; there is a indirect problem above. And that is to do with conditionals in PEG. What I am trying to express should be written as such:
rule = ( eps(_r) << ( /* grammar for when pointer is not null */ ) )
| eps // otherwise dont do anything.
;
I was using the semantic action body ( specified in a [] block), to express the conditional part of the grammar. Strangely though I have written conditional PEG grammars before, I just made a mistake, which led to the second class of problems.
So, eps(_r1) does the trick, The second type of compilation issue is irrelevant to the question.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是 C++03 中 C++ 类型系统的一个基本问题。 值 0 很特殊,可以用在许多类型、
int
不能使用的地方。这个问题很容易证明,并且在模板和指针结合时会导致很多问题。最简单的解决方案是编写
nullptr
的快速版本,可以在 C++0x 中找到它。This is a fundamental problem with the C++ type system in C++03. The value 0 is special and can be used in many places where it's type,
int
, cannot. This problem is easily demonstrated and causes plenty of problems where templates and pointers combine.The simplest solution is to write a quick version of
nullptr
, which can be found in C++0x.正如我的评论中所建议的,使用隐式指针到
bool
转换对于我来说在 Boost 1.46.1 中开箱即用。以下是一个最小的重现,其中当(且仅当)p != 0 && 时,
或parse
成功。 input == "not null"p == 0 && input == "null"
:因此,无论您在尝试以这种方式使用隐式转换时遇到什么问题,它都必须特定于您的代码;即,您必须显示更多代码才能获得任何有用的反馈。
Using implicit pointer-to-
bool
conversion, as suggested in my comment, works for me out of the box with Boost 1.46.1. The following is a minimal repro whereinparse
succeeds if (and only if)p != 0 && input == "not null"
orp == 0 && input == "null"
:So, whatever problem you're having while trying to use implicit conversion in this manner, it must be specific to your code; i.e., you'll have to show more of your code to get any useful feedback.