具有模板函数名称的可变参数模板

湿

遵循这个问题,我试图避免复制粘贴与调用该类mixins的所有同名方法有关的一些代码BaseSensor

在sensor.hpp中

struct EdgeSensor //a mixin
{
    void update(){}
    void printStats() {}
};

struct TrendSensor //another mixin
{
    void update(){}
    void printStats() {}
};

template<typename ... SensorType>
class BaseSensor : public SensorType ... //to my BaseSensor class
{
    void update() /*{ what goes in here??? }*/
    void printStats() /*{ what goes in here??? }*/
};

在sensor.t.hpp中

template<typename ... SensorType>
void BaseSensor<SensorType...>::update()
{
    int arr[] = { (SensorType::update(), 0)..., 0 };
    (void)arr;
}

template<typename ... SensorType>
void BaseSensor<SensorType...>::printStats()
{
    int arr[] = { (SensorType::printStats(), 0)..., 0 };
    (void)arr;
}

在main.cpp中

int main(int , const char **) 
{
    {
        BaseSensor<EdgeSensor,TrendSensor> ets;
        ets.update();
        ets.printStats();
    }
    {
        BaseSensor<EdgeSensor> ets;
        ets.update();
        ets.printStats();
    }
}

上面的代码update()依次执行所有mixin的操作,然后继续执行所有printStats()mixin的所有操作。

我想知道是否有可能避免重复的实现,BaseSensor::update()BaseSensor::printStats()创建一个通用(模板)函数来接受要在所有mixin中执行的目标函数的名称:

例如,我可以创建一个方法 runAll()

template<typename ... SensorType>
class BaseSensor : public SensorType ... //to my BaseSensor class
{
    void update() /*{ what goes in here??? }*/
    void printStats() /*{ what goes in here??? }*/

    template<typename FnName>
    void runAll(FnName f)
    {
        int arr[] = { (SensorType::f(), 0)..., 0 };
        (void)arr;
    }
};

如何将我叫它然后从BaseSensor::update()BaseSensor::printStats()我尝试使用

void update() { runAll<update>(); }
void printStats() { runAll<printStats>(); }

但这是行不通的(没想到会这样)。将函数名称作为函数参数传递的问题(我看到的还有其他许多问题,例如这里的问题是,我不知道如何从中指向各种::update()函数BaseSensor::update()

void update() { runAll<update>( update() ); }

也不正确。

在这种情况下是否可以避免复制?如果将runAll()文件移至“ sensor.t.hpp”文件中,模板参数将如何显示?

谢谢

WF

我想到了另一个纯c ++ 11答案。这一个使用标签调度和非类型模板参数:

template <class T, void (T::*)()>
struct Method { };

template<typename ... SensorType>
class BaseSensor : public SensorType ... //to my BaseSensor class
{
   template <class T, void(T::*M)()>
   int runSingle(Method<T, M>) {
      (this->*M)();
      return 0;
   }

   template <class... Ts>
   void runAll() {
      int run[sizeof...(Ts)] = { runSingle(Ts{})... };
      (void)run;
   }

public:
    void update() {
       runAll<Method<SensorType, &SensorType::update>...>();
    }
    void printStats() {
       runAll<Method<SensorType, &SensorType::printStats>...>();
    }
};

必须指出的是,除了折叠表达式(包括skypjack的表达式)以外,这些答案中的任何一个都不能处理mixin类的虚拟被调用者方法。但是,我认为skypjack答案可以很容易地修改以达到这样的效果:

#include<type_traits>

// (...)

template<typename ... SensorType>
class BaseSensor : public SensorType ...
{
    template<typename F>
    void execute(F &&f) {
        int arr[] = { (f(static_cast<SensorType&>(*this)), 0)..., 0 };
        (void)arr;
    }

public:
    void update() {
        execute([](auto &t) { t.std::remove_reference<decltype(t)>::type::update(); });
    }

    void printStats() {
        execute([](auto &t) { t.std::remove_reference<decltype(t)>::type::printStats(); });
    }
};

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

具有模板函数名称,传递参数和周围返回值的可变参数模板

具有可变参数模板参数的函数指针

具有可变参数模板的成员函数指针

可变参数模板函数名称查找无法找到专业化

C ++:具有可变参数模板的成员函数指针参数

具有多个参数包的可变参数模板构造函数

具有相同类型参数的可变参数模板化函数

具有相同类型的可变参数模板参数的构造函数无法编译

具有相同参数类型的可变参数模板函数

带有可变参数模板参数的重载函数

C ++中没有参数可变参数模板函数

没有匹配函数调用可变参数模板函数

当typedef名称与可变参数模板参数名称重合时发生GCC错误

具有const引用的可变参数模板

具有双打的C ++可变参数模板

C ++创建具有可变参数模板方法的接口

具有元组的C ++可变参数模板

如何具有类型和大小的可变参数模板?

具有递归继承并使用声明的可变参数模板

具有编译问题的简单(递归)可变参数模板“ accumulate_for”函数

获取在C ++ 11中具有可变参数模板的函数的地址

具有左值和右值的可变参数模板类构造函数

具有依赖类型的c ++ 11可变参数函数模板是否不明确?

从具有可变参数模板构造函数的类型构造 std::function 对象

可变参数模板,没有匹配的调用函数

可变参数模板对

递归可变参数函数模板

编写可变参数模板构造函数

如何重载可变参数模板函数?