将函数应用于元组中的每个元素,将每个元素转换为类型包中的不同类型,然后作为参数包传递

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

我正在构建一个复杂的可扩展系统。细节并不重要,但是除了这一期,我真的很喜欢设计。

我有一个类型T的接口WithState<T> : Subject。>>

有问题的类以template <typename... StateTypes>为模板。

它具有std::tuple<std::shared_ptr<WithState<StateTypes>>...>>

我有一个函数std::any getStateFor(std::shared_ptr<Subject>)(其中WithState<T> : Subject)。

我也有一个函数void handleStates(StateTypes... states)(在这一点上,也可以取一个元组,更容易些)]

现在我需要将所有这些部分插入在一起:我需要将元组中的元素上移到shared_ptr<Subject>,然后依次将getStateFor应用于这些元素中的每一个,并将std::any_cast的结果按StateTypes...的顺序进行应用,然后将所有这些作为参数包一次转发到handleStates

((在此之前被标记为XY问题:较高级别的抽象不关心具体的状态类型,而我想以尽可能多的类型安全性来实现较低部分。到目前为止,这种方法对我来说看起来不错需要)

我可能可以通过将元组转换为向量,对每个元组应用getStateFor,然后编写适用于适当的any_cast的递归函数来实现,但是我仍然不知道如何将结果收集到具有不同类型的元组。我想知道这是否适用于智能折叠表达式...

这里是现有代码的骨架:

#include <memory>
#include <tuple>
#include <any>
#include <iostream>
#include <cassert>
#include <functional>

// ignoring references and const for brevity

class Subject { 
public:
  /* deleted copy assignment and constructor */ 
  // this is here so that the example works
  virtual std::any getState() = 0;
};

template <typename T> class WithState : public Subject { };

template <typename... StateTypes>
class StateHandler {
public:   
  std::tuple<std::shared_ptr<WithState<StateTypes>>...> subjects;
  // this one is actually in another class, but it doesn't matter
  void handleStates(StateTypes... states);

  void handleStatesForSubjects(std::function<std::any (std::shared_ptr<Subject>)> getStateFor) {
    // how do I implement this?
  }
};

int main() {
  struct foo { int a; int b; };

  struct WithInt : public WithState<int> { 
    std::any getState() override { return 17; } 
  };
  struct WithFoo : public WithState<foo> {
    std::any getState() override { return foo { 1, 2 }; }
  };

  StateHandler<int, foo> handler;

  handler.subjects = { 
    std::make_shared<WithInt>(), std::make_shared<WithFoo>() };

  handler.handleStatesForSubjects([](auto subj) { return subj->getState(); });
}

on godbolt

但是,这仍然缺少具体类型的std::any_cast

有什么想法吗?

我正在构建一个复杂的可扩展系统。细节并不重要,但是除了这一期,我真的很喜欢设计。我有一个接口WithState :某些类型T的主题。...

c++ templates c++17 variadic-functions
1个回答
1
投票

主要问题是您的元组包含std::shared_ptr<WithState<StateTypes>>...,因此apply会尝试使用它调用给定的lambda,但是lambda只需要StateTypes&&...

© www.soinside.com 2019 - 2024. All rights reserved.