gpt4 book ai didi

c++ - 在语法构造函数中评估的语义 Action (或不?)

转载 作者:搜寻专家 更新时间:2023-10-31 01:42:20 27 4
gpt4 key购买 nike

我一直在学习 boost::spirit 并且遇到了在语法构造期间评估语义 Action 的困惑。以下代码产生输出:

string=

我的假设是此输出作为附加到 orule 的语义操作的一部分。

有没有办法避免这种行为?或者,如果我在语义操作中使用 std::cout,我需要忍受它吗?

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <iostream>
#include <string>

namespace phx = boost::phoenix;
namespace qi = boost::spirit::qi;

template <typename Iterator>
struct my_grammar : qi::grammar<Iterator, std::string( ) >
{
my_grammar() : my_grammar::base_type(orule)
{
using qi::_1;
using qi::_2;
using qi::attr;
using qi::string;
using phx::val;

orule = string("abc") [ std::cout << "string=" << _1 << std::endl ];
}
qi::rule< Iterator, std::string() > orule;
};

int main()
{
typedef std::string::const_iterator iterator_type;
typedef my_grammar<iterator_type> parser;
parser my_parser; // Our grammar
return 0;
}

最佳答案

简短回答:不,在规则初始化期间评估语义操作。

但是,您的问题是您没有(只是)编写语义操作。


是的,在您的例子中是该表达式的第一部分

std::cout << "string=" << _1 << std::endl

有副作用:(std::cout << "string=")将文字插入标准 ostream 对象,然后 返回 std::cout引用。

这是因为您使用了 std::operator<<在标准库中定义,而不是 boost::phoenix::....::operator<< ¹.


您可以通过强制第二个参数的类型来选择正确的重载来解决这个问题:

std::cout << phx::val("string=") << _1 << std::endl

当然,您始终可以通过执行以下操作来加倍确定

phx::ref(std::cout) << _1 << std::endl

但是您会注意到,人们往往会尽可能地跳过它。第二个操作数是 boost::spirit::_1已经引入表达式模板上下文(即选择非标准运算符重载来构造惰性参与者而不是副作用)。


¹ 这可能最终只是 boost::proto::....::operator<<无论如何,但这就是所有美妙的实现细节:)

关于c++ - 在语法构造函数中评估的语义 Action (或不?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27070554/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com