c++ - 具有模板函数名称和传递参数和返回值的可变参数模板

标签 c++ c++11 variadic-templates

来自 this问题,我一直在尝试创建一个模板函数来调用其混入的所有同名方法。这已在上一个问题中完成并验证。

现在我试图获取 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();
  }
}

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

如果我尝试创建 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,所以应该没问题

关于c++ - 具有模板函数名称和传递参数和返回值的可变参数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39650751/

相关文章:

c++ - Windows 中的 wxwidgets 错误

安卓NDK : How to get screen resolution in native binary?

c++ - 使用 std::vector<boost::shared_ptr<Base_Class>> 或 boost::ptr_vector<Base> 的性能考虑因素是什么?

c++ - 从基类构造函数调用派生类的方法

c++ - 创建包含已分配数组的 unique_ptr 的正确方法

c++ - 如何使用成员函数映射参数包? (非递归,预折叠表达式)

c++ - 如何将可变参数模板函数声明为友元?

c++ - LLVM:如何修复 "Referring to an argument in another function"

c++ - 为什么 sizeof (class with character variable) 在 C++ 中异常?

C++ 模板 std::tuple 到 void* 并返回