使用模板参数列表中的参数包

问题描述 投票:0回答:1

我想编写一个抽象的

Pipeline
类,它获取一些具有特定签名的函数作为模板参数,并根据输入数据的解析阶段运行它们。这是我写的代码:

#include <array>

enum class ParseState
{
  EXTRACTED,   /**< EXTRACTED */
  IN_PROGRESS, /**< IN_PROGRESS */
  REJECTED,    /**< REJECTED */
};

struct ParseStage
{
  std::size_t stage;

public:
  ParseStage() : stage(0)
  {}

  std::size_t get_stage() const
  {
    return stage;
  }

  std::size_t next_stage()
  {
    return ++stage;
  }

  void reset()
  {
    stage = 0;
  }
};

template <typename InputDataType>
using ParseResult = std::pair<ParseState, InputDataType>;

template <typename InputDataType, typename ParserState, typename... Args>
using StageFunctionRefType = ParseResult<InputDataType> (&)(const InputDataType &, ParserState &, Args... args);

template <typename InputDataType, typename ParserState, typename... Args,
          StageFunctionRefType<InputDataType, ParserState, Args...>... StageFunctions>
class Pipeline
{
  static constexpr std::array Stages{ StageFunctions... };

public:
  static ParseResult<InputDataType> feed(const InputDataType &input_data, ParserState &parser_state,
                                         ParseStage &parse_stage, Args... args)
  {
    if (parser_state.parse_state == ParseState::REJECTED)
      return { ParseState::REJECTED, input_data };

    auto remaining_data = input_data;

    while (parse_stage.get_stage() < Stages.size() && remaining_data.size())
    {
      const auto parse_result = Stages[parse_stage.get_stage()](remaining_data, parser_state, args...);
      remaining_data = parse_result.second;
      if (parse_result.first == ParseState::EXTRACTED)
        parse_stage.next_stage();
      else if (parse_result.first == ParseState::REJECTED)
        return parse_result;
    }

    if (parse_stage.get_stage() == Stages.size())
      return { ParseState::EXTRACTED, remaining_data };

    return { ParseState::IN_PROGRESS, remaining_data };
  }
};

但我收到一条错误消息:

parameter pack 'Args' must be at the end of the template parameter list 

我该如何解决这个问题?或者您还有其他解决方案吗? 性能对我来说非常重要,所以我想避免使用虚拟或

std::function

c++ templates variadic-templates parameter-pack
1个回答
0
投票

基于如何在可变参数模板中拥有多个参数包?

您正在寻找类似的东西

template <typename... Args>
using foo = void (*)(Args... args);

template <auto...>
class FoosHolder;

template <typename... Args,
          foo<Args...>... Foos>
class FoosHolder<Foos...>
{
};

void foo1(int){}
void foo2(int, double){}

int main() {
    FoosHolder<foo1, foo1> f1;
    FoosHolder<foo2, foo2> f2;
}
© www.soinside.com 2019 - 2024. All rights reserved.