带有模板函数名称并传递参数和返回值的可变参数模板

2024-01-11

以下来自this https://stackoverflow.com/questions/39558976/variadic-templates-with-template-function-names/39570187?noredirect=1#comment66603297_39570187问题,我一直在尝试创建一个模板函数来调用其 mixin 的所有同名方法。这已经在上一个问题中完成并验证了。

现在我正在尝试获取 SensorType:: 的返回值

解析:

#include<iostream>
#include <string>

struct EdgeSensor
{
    void update(int i) { std::cout << "EdgeSensor::update " << i <<  std::endl; }
    void updat2(const int i ) { std::cout << "EdgeSensor::updat2" << i << std::endl; }
    std::string printStats() { std::cout << "EdgeSensor::printStats" << std::endl; 
                               return std::string("EdgeSensor::printStats"); }
};

struct TrendSensor
{
    void update(int i ) { std::cout << "TrendSensor::update" << i << std::endl; }
    void updat2(const int i ) { std::cout << "TrendSensor::updat2" << i << std::endl; }
    std::string printStats() { std::cout << "TrendSensor::printStats" << std::endl; 
                               return std::string("TrendSensor::printStats"); }
};

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

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

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

public:
    void update() {
       runAll<Method<SensorType, &SensorType::update>...>(2);
    }
    void updat2() {
       const int k = 3;
       runAll<Method<SensorType, &SensorType::updat2>...>(k);
    }
    void printStats() {
    //   runAll<Method<SensorType, &SensorType::printStats>...>();
    }
};

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

  {
    BaseSensor<EdgeSensor> ets;
    ets.update();
    ets.updat2();
    ets.printStats();
  }
}

以上编译并运行良好。问题是:如何收集运行 mixin 的返回值(std::strings)SensorType::printStats()中的方法BaseSensor::printStats() ?

如果我尝试创建第二个版本run*功能和Method模板,我无法编译它。说我做了:

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

template <class T, void(T::*M)()>
int runSingle2(Method2<T, M>) {
    (this->*M)();
    return 0;
}

template <class... Ts>
void runAll2() {
    std::string s;
    int run[sizeof...(Ts)] = { s = runSingle2(Ts{})... };
    (void)run;
    std::cout << "s=" << s << std::endl;
}

public:
    void update() {
        int k = 4;
        runAll<Method<SensorType, &SensorType::update>...>(k);
    }
    void printStats() {
        runAll2<Method2<SensorType, &SensorType::printStats>...>();
    }
};

这不编译说

g++ -Wall -Wextra -g -std=c++11   -c -o "obj_dbg/main.opp" "main.cpp"
main.cpp: In instantiation of ‘void BaseSensor<SensorType>::printStats() [with SensorType = EdgeSensor, TrendSensor]’:
main.cpp:65:20:   required from here
main.cpp:58:8: error: could not convert template argument ‘&EdgeSensor::printStats’ to ‘void (EdgeSensor::*)()’
make: *** [obj_dbg/main.opp] Error 1

那么我怎样才能从中获取返回值SensorType::printStats()?


不确定是否可以使用c++11,如果可以,那么我认为这是最简单的?

#include <iostream>
#include <string>

struct EdgeSensor
{
    void update(int i) { std::cout << "EdgeSensor::update " << i <<  std::endl; }
    void updat2(const int i ) { std::cout << "EdgeSensor::updat2" << i << std::endl; }
    std::string printStats() { std::cout << "EdgeSensor::printStats" << std::endl; 
                               return std::string("EdgeSensor::printStats"); }
};

struct TrendSensor
{
    void update(int i ) { std::cout << "TrendSensor::update" << i << std::endl; }
    void updat2(const int i ) { std::cout << "TrendSensor::updat2" << i << std::endl; }
    std::string printStats() { std::cout << "TrendSensor::printStats" << std::endl; 
                               return std::string("TrendSensor::printStats"); }
};

template<typename ... SensorType>
class BaseSensor : public SensorType ... //to my BaseSensor class
{
public:
    void update() {
       auto v = { (static_cast<SensorType*>(this)->update(1), 0)... }; // *
       (void) v;
    }
    void updat2() {
       const int k = 3;
       auto v = { (static_cast<SensorType*>(this)->updat2(k), 0)... }; // *
       (void) v;
    }
    void printStats() {
       auto v = { static_cast<SensorType*>(this)->printStats()... };
       for (auto s : v) {
           std::cout << s << std::endl;
       }
    }
};

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

  {
    BaseSensor<EdgeSensor> ets;
    ets.update();
    ets.updat2();
    ets.printStats();
  }
}
  • 注意:我在这里使用的是 gcc 扩展,但我认为你正在使用 gcc,所以应该没问题
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

带有模板函数名称并传递参数和返回值的可变参数模板 的相关文章

随机推荐