【问题标题】:static expressions for method chaining C++用于方法链接 C++ 的静态表达式
【发布时间】:2021-04-26 08:09:06
【问题描述】:

我正在实现一个解析器库,并希望用户通过方法链接来定义解析器。但是,当通过头文件中的方法链接定义,然后在.cpp 中调用时,它将返回分段错误,因为中间结果不是静态的。如果我将它们分成静态变量,它就可以工作。

是否有一种解决方法仍然能够通过方法链接来定义我的解析器而无需这种冗长?

static Parser<int> term1 = binop_add.alt(binop_sub).map<int>(int_of_either_ints);
// segmentation fault

static Parser<Either<int,int>> term1_alt = binop_add.alt(binop_sub);
static Parser<int> term1 = term1_alt.map<int>(int_of_either_ints);
// works fine

这里调用alt 的结果会生成一个中间解析器,然后与map 链接以生成另一个解析器。当我在其上调用实际的解析方法时,将它们链接起来会直接导致分段错误,因为中间解析器已经超出了我假设的范围和 gced。

编辑: 我正在考虑使用constexpr,但我对Parser 的定义涉及std::stringstd::function,这使得它不可行。

【问题讨论】:

  • C++ 没有垃圾收集(你说“我假设 gced”)。发布完整的代码,否则这不是一个有效的问题。
  • 您能提供更多代码吗?如果有一些可以玩的东西,比如WandboxOnlineGDB 等在线编译器上的项目,那就太好了...特别是 OnlineGDB 非常适合涉及头文件和源文件的代码。像底层函数的最小工作示例这样的东西会很好......
  • 临时变量在表达式结束时被销毁。目前尚不清楚您的解决方案如何修复它,如果没有 minimal reproducible example,我们不知道您要修复什么

标签: c++ static c++14 method-chaining


【解决方案1】:

我通过将解析器组合器更改为返回 new Parser&lt;...&gt;(...) 并使用指针而不是值来组合解析器来修复它。

之后:

Parser<Either<T, U>>* alt(std::string l, const Parser<U> *b) const
  {
    return new
    Parser<Either<T, U> >(l, [&, b](State &s) {
      State _s = s;
      try
      {
        return Left<T, U>(parse(s));
      }
      catch (std::vector<State> e)
      {
        return Right<T, U>(b->parse(_s));
      }
    });
  }

之前:

Parser<Either<T, U>> alt(std::string l, Parser<U> b) const
  {
    return Parser<Either<T, U> >(l, [&, b](State &s) {
      State _s = s;
      try
      {
        return Left<T, U>(parse(s));
      }
      catch (std::vector<State> e)
      {
        return Right<T, U>(b.parse(_s));
      }
    });
  }

工作方法链现在看起来像这样

static Parser<int>* term1 = binop_add->alt("term1", binop_sub)->map<int>(int_of_either_ints);

【讨论】:

  • 这只是乞求内存泄漏。至少使用智能指针。
猜你喜欢
  • 1970-01-01
  • 2017-10-30
  • 1970-01-01
  • 1970-01-01
  • 2010-09-12
  • 1970-01-01
  • 2011-06-26
  • 1970-01-01
  • 2018-01-01
相关资源
最近更新 更多