如何在一个构造函数中使用两个可变参数模板参数来绑定两个函数?

时间:2016-06-08 12:42:06

标签: c++ templates

我想构造一个对象,它传递两个带有可变参数个数的函数:

class PhaseSetControlProperty : public ControlProperty {

  public:
    template<typename FuncKicked, typename... ArgsKicked, typename FuncActivated, typename... ArgsActivated>
    PhaseSetControlProperty(const std::vector<std::string> &kickedPhaseNames, const std::vector<std::string> &activatedPhaseNames, FuncKicked funcKicked, ArgsKicked ...argsKicked, FuncActivated funcActivated, ArgsActivated... argsActivated): ControlProperty("PhaseSetControl")
    {
    getModel()->addProperty(new StringListProperty("kickedPhaseNames", kickedPhaseNames));
    getModel()->addProperty(new StringListProperty("activePhaseNames", activatedPhaseNames));

    getModel()->addProperty(new StringListProperty("activated", activatedPhaseNames, funcActivated, argsActivated...));
    getModel()->addProperty(new StringListProperty("kicked", kickedPhaseNames, funcKicked, argsKicked...));
    }
};

实例化如下:

model->addProperty(new PhaseSetControlProperty(kickedphasenames, activephasenames, &BDlines::kickedPhasesFunctionCallback, this, std::placeholders::_1, &BDlines::activePhasesFunctionCallback, this, std::placeholders::_1));

这和std :: placeholders :: _ 1是可变参数。

之前的解决方案如下:

kicked_property = new FunctionProperty("kicked", &BDlines::kickedPhasesFunctionCallback, this, std::placeholders::_1);
  activated_property = new FunctionProperty("activated", &BDlines::activePhasesFunctionCallback, this, std::placeholders::_1);

C ++如何知道哪些参数属于哪些模板参数?如何以简单的方式实现这一目标?

我目前的解决方案是使用两个额外的功能来添加属性&#34;激活&#34;然后财产&#34;踢了#34;,基本上像旧版本,但我想只使用一个电话。

3 个答案:

答案 0 :(得分:2)

您可以使用std::tuple<>来收集参数 - 例如..

template <typename... Args1, typename... Args2>
void foo(const tuple<Args1...>& t1, const tuple<Args2...>& t2) {
    cout << tuple_size<tuple<Args1...>>::value << ' ' << tuple_size<tuple<Args2...>>::value << endl;
}

现在将元组传播到构造函数...

答案 1 :(得分:0)

  

C ++如何知道哪些参数属于哪些模板参数?

没有。这就是为什么模板参数包只有在它们是最后一个参数时才可以推导出来的原因。

  

如何以简单的方式实现这一目标?

如果每组参数仅用于构造属性,则可以使用属性的参数包:

model->addProperty(new PhaseSetControlProperty(kickedphasenames, activephasenames,
    new StringListProperty (&BDlines::kickedPhasesFunctionCallback, this, std::placeholders::_1),
    new StringListProperty (&BDlines::activePhasesFunctionCallback, this, std::placeholders::_1)));

还有额外的好处,也支持其他种类和数量的产权。

答案 2 :(得分:0)

不确定我是否完全理解了您的问题,但是您是否可以将仿函数作为模板参数传递而不是单独传递函数和参数?所以你的代码看起来像:

template<typename FuncKickedFunctor, typename FuncActivatedFunctor>
    PhaseSetControlProperty(const std::vector<std::string> &kickedPhaseNames, const std::vector<std::string> &activatedPhaseNames, FuncKickedFunctor funcKickedFunctor, FuncActivatedFunctor funcActivatedFunctor): ControlProperty("PhaseSetControl")
    {
    getModel()->addProperty(new StringListProperty("kickedPhaseNames", kickedPhaseNames));
    getModel()->addProperty(new StringListProperty("activePhaseNames", activatedPhaseNames));

    getModel()->addProperty(new StringListProperty("activated", activatedPhaseNames, funcActivatedFunctor));
    getModel()->addProperty(new StringListProperty("kicked", kickedPhaseNames, funcKickedFunctor));
    }