【问题标题】:Boost.Spirit with Boost.Variant and C++11: Expecting a zero-argument constructorBoost.Spirit 与 Boost.Variant 和 C++11:期望零参数构造函数
【发布时间】:2012-04-13 08:13:16
【问题描述】:

我正在尝试使用 Boost.Spirit 编译一个简单的语法。我在 Arch Linux x86_64 上使用 g++ 4.7.0 和 boost 1.49.0-1.1。

这里的最终目标是汇编程序。将有多个操作数,每个操作数都有一个类。所有操作数类型一起存储在boost::variant 类型中。

当它也是语法的 base_type 时,我已经成功地将这个示例编译到 direct 规则,但是引入 operand 规则(并使其成为基本类型)导致 g++ 4.7.0 抱怨那:

example.cpp:61:7:   required from ‘Grammar<Iterator>::Grammar() [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >]’
example.cpp:76:21:   required from here
/usr/include/boost/spirit/home/qi/detail/attributes.hpp:23:63: error: no matching function for call to ‘DirectOperand::DirectOperand()’
/usr/include/boost/spirit/home/qi/detail/attributes.hpp:23:63: note: candidates are:
example.cpp:20:12: note: DirectOperand::DirectOperand(const DirectValue&)
example.cpp:20:12: note:   candidate expects 1 argument, 0 provided
example.cpp:16:7: note: DirectOperand::DirectOperand(const DirectOperand&)
example.cpp:16:7: note:   candidate expects 1 argument, 0 provided

我不明白为什么它应该为DirectOperand 寻找默认构造函数,因为语义操作应该使用构造函数调用它。

我尝试了很多变化,包括

operand = directOp[_val = _1];

甚至编写一个辅助函数来“强制”类型,例如:

static Operand makeDirectOperand( const DirectOperand& op ) { return op; }

// ...

operand = directOp[&makeDirectOp];

但无论我做什么,它都会抱怨缺少默认构造函数。

当我真正定义一个零参数的构造函数时,我发现它编译了,但是 DirectOperand::value_ 从未改变我分配的默认值。

这是代码。尽可能短。

#include <cstdint>
#include <iostream>
#include <string>

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_uint.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/variant.hpp>

typedef std::uint16_t DataWord;
typedef boost::variant<std::string, DataWord> DirectValue;

class DirectOperand {
private:
  DirectValue value_;
public:
  explicit DirectOperand( const DirectValue& value ) :
  value_( value ) {}

  const DirectValue& value() const { return value_; }
};

// For example purposes, but there will be multiple operand types
// here.
typedef boost::variant<DirectOperand> Operand;

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

template <typename Iterator>
struct Grammar : qi::grammar<Iterator, Operand(), ascii::space_type> {
   Grammar() : Grammar::base_type( operand ) {
      using qi::lexeme;
      using ascii::char_;
      using qi::uint_parser;
      using namespace qi::labels;

      uint_parser<DataWord, 16, 1, 4> uhex_p;
      uint_parser<DataWord, 10, 1, 5> uint_p;

      word =
        char_( "a-zA-Z._" ) [_val += _1]
        >> *char_( "a-zA-Z0-9._" ) [_val += _1]
        ;

      number = (
        "0x" >> uhex_p
        | uint_p
        )
        [_val = _1]
        ;

      direct %= ( word | number );

      directOp %= direct;

      // This would be ( directOp | indirectOp | etc)
      operand %= directOp;
   }

  qi::rule<Iterator, DataWord(), ascii::space_type> number;
  qi::rule<Iterator, std::string()> word;
  qi::rule<Iterator, DirectValue(), ascii::space_type> direct;
  qi::rule<Iterator, DirectOperand(), ascii::space_type> directOp;
  qi::rule<Iterator, Operand(), ascii::space_type> operand;
};

int main() {
   std::string line;

   typedef std::string::iterator iterator_type;
   typedef Grammar<iterator_type> Grammar;
   Grammar grammar {};
}

【问题讨论】:

    标签: c++ boost c++11 boost-spirit boost-variant


    【解决方案1】:

    我相信属性qi::rule(这里是directOp)的实例化需要一个默认的构造函数。

    如果您不愿意在 DirectOperand 中包含默认构造函数,您可以尝试将其包装在 boost::optional 中以延迟初始化。

    【讨论】:

    • 是的,这就是问题所在。 Boost.Optional 很好地解决了这个问题。我对调用默认构造函数时的垃圾问题的评论实际上是由于缺少调试符号。
    • 在某些情况下,“可选”似乎不适用于 x3。您能否解释一下 Qi 中究竟是什么取消引用选项?
    • @IgorR.: 抱歉,我已经有将近 5 年没有和 Qi 合作了,所以我不知道 :(
    • @sehe 也许你可以安排一些亮点?
    • @IgorR。这是move_toboost::spirit::x3 中的其他特征。如果您有“它不起作用”的特定情况,我可能能够解释它或确认错误
    猜你喜欢
    • 2013-12-24
    • 2015-06-17
    • 2016-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 1970-01-01
    • 2020-09-26
    相关资源
    最近更新 更多