构造函数自行处理时,要解压缩可变参数模板类吗?

时间:2019-04-29 18:08:02

标签: c++ templates c++17 variadic-templates fold-expression

这是后续of my last post。我已经成功地能够设置和获取类的值。但是,现在我正在尝试进一步,并让构造函数将自身作为参数。但是,我不确定如何正确打开包装。

我尝试过:

#ifndef CONTROLLER_HPP
#define CONTROLLER_HPP

#include <functional>
#include <vector>
#include <iostream>

class Controller
{

  public:
    template <class...Classes>
    Controller(Classes & ...classes) 
    { 
      toSet = [&](int val){(classes.updateValue(val), ...); }; 
      toGet = [&](std::vector<int> &values)
      {
        int size[sizeof...(Classes)] = { (classes.get())...};
        for(const auto &e: size) values.push_back(e); 
      }; 
    }

    // TODO: Find out how to create one master group if more than one are created.
    //template <Controller&...Controllers, class...Classes>
    template <class...Classes>
    Controller(Controller& controllers(Classes&...classes)...) : Controller(classes&...c){};

    void setValues(int val)
    {
      toSet(val);
    }

    std::vector<int> getValues()
    {
      std::vector<int> values;
      toGet(values);
      return values;
    }

  private:
    std::function<void(int)> toSet;
    std::function<void(std::vector<int>&)> toGet;
};

#endif

但是,在这种情况下,当我尝试将其传递给初始控制器构造函数时遇到classes was not declared in this scope错误。我也尝试了注释掉的模板声明,但是我也不认为这是正确的。我也尝试过Controller&...controllers(Classes&...)...) : (Controller(Classes&...classes));,但这也不起作用。

我真的不知道下一步该怎么做,或者我问的是否有可能做。或者,如果我对整个课程进行模板化,这可能会更容易。我只是想避免使用Controller<A,B> controller(A,B);而是创建Controller controller(A,B)。但是,我知道是否必须采用其他方式。

编辑:我应该阐明我要做什么:

int main()
{
  ClassA A;
  ClassB B;
  ClassC C;
  ClassD D;

  Controller controller1(A,B);
  Controller controller2(C,D);

  Controller master(controller1,controller2);

  master.setValues(20);

  std::vector<int> getVals = master.getValues();

  for(const auto& e: getVales) std::cout << e << " ";
}

然后将设置所有类的所有值,并获取控制器内所有类的值。

1 个答案:

答案 0 :(得分:0)

在可以递归管理的类中进行转换Controller呢?

简化:如何在控制器中添加updateValue()get()

void updateValue (int v0)
 { setValues(v0); }

auto get () const
 { return getValues(); } 

根据情况,仅保留修改toGet函数以附加单个值或值向量。

我的意思是...给出了如下两种重载的append()方法

  static auto append (std::vector<int> & v0, std::vector<int> const & v1)
   { v0.insert(v0.end(), v1.cbegin(), v1.cend()); }

  static auto append (std::vector<int> & v0, int i)
   { v0.emplace_back(i); }

您可以按照以下方式简单地编写构造函数

template <typename ... Cs>
Controller (Cs & ... cs)
   : toSet{[&](int v){ (cs.updateValue(v), ...); }},
     toGet{[&](auto & vs){ (append(vs, cs.get()), ...); }}
 { }

以下是完整的编译示例

#include <vector>
#include <iostream>
#include <functional>

template <std::size_t>
class ClassTmpl
 {
   private:
      int val;

   public:
      void updateValue (int v0)
       { val = v0; }

      int get () const
       { return val; }
 };

using ClassA = ClassTmpl<0u>;
using ClassB = ClassTmpl<1u>;
using ClassC = ClassTmpl<2u>;
using ClassD = ClassTmpl<3u>;

class Controller
 {
   private:
      std::function<void(int)> toSet;
      std::function<void(std::vector<int>&)> toGet;

      static auto append (std::vector<int> & v0, std::vector<int> const & v1)
       { v0.insert(v0.end(), v1.cbegin(), v1.cend()); }

      static auto append (std::vector<int> & v0, int i)
       { v0.emplace_back(i); }

   public:

      template <typename ... Cs>
      Controller (Cs & ... cs)
         : toSet{[&](int v){ (cs.updateValue(v), ...); }},
           toGet{[&](auto & vs){ (append(vs, cs.get()), ...); }}
       { }

      void setValues (int val)
       { toSet(val); }

      void updateValue (int v0)
       { setValues(v0); }

      auto getValues () const
       {
         std::vector<int> values;
         toGet(values);
         return values;
       }

      auto get () const
       { return getValues(); }
 };

int main ()
 {
   ClassA A;
   ClassB B;
   ClassC C;
   ClassD D;

   Controller controller1(A, B);
   Controller controller2(C, D);

   Controller master(controller1, controller2);

   master.setValues(20);

   std::vector<int> getVals = master.getValues();

   for ( auto const & e : getVals )
      std::cout << e << ' ';

   std::cout << std::endl;
 }