作为模板参数

时间:2017-03-17 20:43:19

标签: c++ c++11 templates dry

我试图通过编写模板函数来避免这种重复的代码。

#include <algorithm>
class X {

public:
void get_amin(double *a){}
void set_amin(double a){}

void get_bmin(double *b){}
void set_bmin(double b){}

//...many pairs like above

};
int main(){
      X *x1 = new X;
      X *x2 = new X;

      //code that will be repeated
      {
          double x1_amin;
          x1->get_amin(&x1_amin);
          double x2_amin;
          x2->get_amin(&x2_amin);          
          x1->set_amin(std::min(x1_amin, x2_amin));
      }
      //repeatation
      {          
          double x1_bmin;
          x1->get_bmin(&x1_bmin);
          double x2_bmin;
          x2->get_bmin(&x2_bmin);          
          x1->set_bmin(std::min(x1_bmin, x2_bmin));
      }
      //
      delete x1;
      delete x2;
}

现在我的尝试在下面。我似乎能够编写模板但无法使用它。堆栈溢出的其他帖子主要关注如何编写模板。另外,我找不到使用类成员函数的示例。

#include <algorithm>
#include <functional>
class X {

public:
void get_amin(double *a){}
void set_amin(double a){}

void get_bmin(double *b){}
void set_bmin(double b){}

//...many pairs like above

};

template <typename F11,typename F12, typename F2>
void templatisedFunction(F12 f11,F12 f12,F2 f2)
{
    double x1_amin;
    f11(&x1_amin);

    double x2_amin;
    f12(&x2_amin);       

    f2(std::min(x1_amin, x2_amin));
}

int main(){

    X *x1 = new X;
    X *x2 = new X;

    //templatisedFunction(x1->get_amin,x2->get_amin,x1->set_amin);
    //templatisedFunction(x1->get_amin(double*),x2->get_amin(double*),x1->set_amin(double));


    //templatisedFunction<x1->get_amin(double*),x2->get_amin(double*),x1->set_amin(double)>();
    //templatisedFunction<x1->get_amin,x2->get_amin,x1->set_amin>();

    std::function<void(X*)> memfun(&X::get_amin);//not sure here
    //templatisedFunction<x1->get_amin,x2->get_amin,x1->set_amin>();

    //
    delete x1;
    delete x2; 
}

2 个答案:

答案 0 :(得分:1)

void (X::*getf)(double *)void (X::*setf)(double)是指向您需要的成员函数的两个指针的函数签名。

使用C ++ 11:

int main()
{
    X x1;
    X x2;

    auto lamb = [&](void (X::*getf)(double *), void (X::*setf)(double))
    {
        double x1_amin;
        (x1.*getf)(&x1_amin);
        double x2_amin;
        (x2.*getf)(&x2_amin);          
        (x1.*setf)(std::min(x1_amin, x2_amin));
    };

    lamb(&X::get_amin, &X::set_amin);
    lamb(&X::get_bmin, &X::set_bmin);
    return 0;
}

答案 1 :(得分:0)

您可以使用指向成员函数的指针来减少重复:

void set_min(X &x1, X &x2, void (X::*get_min)(double *), void (X::*set_min)(double)) {
    double x1_amin;
    (x1.*get_min)(&x1_amin);
    double x2_amin;
    (x2.*get_min)(&x2_amin);
    (x1.*set_min)(std::min(x1_amin, x2_amin));
}

这样使用:

set_min(*x1, *x2, &X::get_amin, &X::set_amin);
set_min(*x1, *x2, &X::get_bmin, &X::set_bmin);

如果你有很多对,你可以更进一步使用循环:

std::pair<void (X::*)(double *), void (X::*)(double)> get_set_pairs[] = {
    {&X::get_amin, &X::set_amin},
    {&X::get_bmin, &X::set_bmin},
};
for (auto &get_set_pair : get_set_pairs){
    set_min(*x1, *x2, get_set_pair.first, get_set_pair.second);
}