可变参数模板与模板函数名称和传递参数和返回值 [英] variadic templates with template function names and passing arguments and return values around

查看:110
本文介绍了可变参数模板与模板函数名称和传递参数和返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题,我一直在试图创建一个模板函数,调用其mixins的所有相同命名的方法。这在上一个问题中已经完成和验证。



现在我试图获得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中运行mixin SensorType :: printStats()方法收集返回值(std :: strings) :printStats()



如果我尝试创建一个二进制版本的 run * 函数和方法模板,我无法使其编译。说我做了:

 模板< 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 -oobj_dbg / main.oppmain.cpp
main.cpp: void BaseSensor< SensorType> :: printStats()[with SensorType = EdgeSensor,TrendSensor]':
main.cpp:65:20:从这里需要
main.cpp:58:8:error:could不将模板参数'& EdgeSensor :: printStats'转换为'void(EdgeSensor :: *)()'
make:*** [obj_dbg / main.opp]错误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,所以应该是好的


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

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()?

解决方案

Not sure if you can use c++11, if so, then I think this is the easiest?

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

  • NOTE: I am using a gcc extension here, but I think you are using gcc, so it should be okay

这篇关于可变参数模板与模板函数名称和传递参数和返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆