jeudi 22 septembre 2016

variadic templates with template function names and passing arguments and return values around

following from this question, I have been trying to create a template function that calls all same-named methods of its mixins. This has been done and verified in the previous question.

Now I am attempting to get the return value of SensorType::

Analytically:

#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();
  }
}

The above compiles and runs fine. The problem is: how can I gather the return values (std::strings) from running the mixin SensorType::printStats() methods in BaseSensor::printStats() ?

If I try to create a 2ndary version of the run* functions and the Method template, I fail to make it compile. Say I did:

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

template int runSingle2(Method2) { (this->*M)(); return 0; }

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

public: void update() { int k = 4; runAll...>(k); } void printStats() { runAll2...>(); }

This does not compile saying

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

So HOW can I grab the return values from SensorType::printStats()?

Thank you

Aucun commentaire:

Enregistrer un commentaire