为模板中的元组创建递归函数

时间:2018-05-06 23:20:12

标签: c++ recursion variadic-templates

我正在尝试在工厂模式中创建一个递归函数,该函数遍历具有可变数量元素的std :: tuple。我创建了这样的ConsoleShapeFactory:

template<size_t N, typename...Shapes>
class ConsoleShapeFactory : public ShapeFactory {
private:
  //Functions for shape creation
  void MakePoint(std::shared_ptr<CAD::Point>);

  //Recursive Router for shapes
  void MakeShapeRouter(std::tuple<Shapes...>&);

public:

  //Create Object Function
  std::tuple<Shapes...> CreateShapeTuple();


};

CreateShapeTuple方法的定义如下:

template<size_t N, typename...Shapes>
std::tuple<Shapes...> ConsoleShapeFactory<N, Shapes...>::CreateShapeTuple() {

  //Define return tuple and get size
  std::tuple<Shapes...> returnTuple;

  MakeShapeRouter(returnTuple);

  return returnTuple;

}

递归的MakeShapeRouter函数看起来像这样(这不起作用):

template<size_t N, typename...Shapes>
void ConsoleShapeFactory<N, Shapes...>::MakeShapeRouter(std::tuple<Shapes...>& tupShapes) {
  MakePoint(std::tuple::get<N-1>(tupShapes));

  ConsoleShapeFactory<N-1, Shapes...>::MakeShapeRouter(tupShapes); //This doesn't work
} 

我对基础案例的尝试看起来像这样:

template<size_t N, typename...Shapes>
void ConsoleShapeFactory<1, Shapes...>::MakeShapeRouter(std::tuple<Shapes...>& tupShapes) {

  MakePoint(std::tuple::get<0>(tupShapes));
}

我不确定如何设置我的MakeShapeRouter函数,以便可以递归调用它并以基本案例退出。我想做什么甚至可能?

*编辑

如果有帮助,我想在主方法中调用该函数:

int main()
{
  auto factory = ConsoleShapeFactory<2, std::shared_ptr<CAD::Point>, std::shared_ptr<CAD::Point>>();

  std::tuple<std::shared_ptr<CAD::Point>, std::shared_ptr<CAD::Point>> shapeTuple = factory.CreateShapeTuple();

  return 0;
}

*编辑2

MakePoint实施:

template<typename...Shapes>
void ConsoleShapeFactory<Shapes...>::MakePoint(std::shared_ptr<CAD::Point>& sp_point) {

  double x, y;

  x = 3;
  y = 4;

  sp_point = std::make_shared<CAD::Point>(x,y);
};

1 个答案:

答案 0 :(得分:1)

您的方法不是static,因此您需要一个实例来调用它们。

ConsoleShapeFactory<N-1, Shapes...>::MakeShapeRouter(tupShapes); //This doesn't work

应该是

ConsoleShapeFactory<N-1, Shapes...>{}.MakeShapeRouter(tupShapes);

但是由于std::index_sequence,可以在没有递归的情况下完成,例如:

template<typename... Shapes>
class ConsoleShapeFactory : public ShapeFactory {
private:
  //Functions for shape creation
  void MakePoint(std::shared_ptr<CAD::Point>);

  template <std::size_t ... Is>
  std::tuple<Shapes...> CreateShapeTuple(std::index_sequence<Is...>)
  {
      std::tuple<Shapes...> res;

      (MakePoint(std::get<Is>(res)), ...); // C++17

      /* or C++11
      const int dummy[] = {0, (MakePoint(std::get<Is>(res)), 0)...};
      static_cast<void>(dummy); // Avoid warning for unused variable.
      */

      return res;
  }

public:
  //Create Object Function
  std::tuple<Shapes...> CreateShapeTuple() {
       return CreateShapeTuple(std::index_sequence_for<Shapes...>());
  }
};