简体   繁体   English

如何将类成员函数作为模板参数传递?

[英]How to pass class member function as template parameter?

I would like to pass class member functions as a template parameter as shown in below example in main function.我想将类成员函数作为模板参数传递,如下面的main函数示例所示。 Could you please help?能否请你帮忙? It is working fine, if I pass normal functions as input parameters.如果我将普通函数作为输入参数传递,它工作正常。

template <int n>
class meta
{
public:
  template <typename F1, typename F2>
  void operator()(F1& f1, F2& f2)
  {
     if (f2())
     {
       f1(n);
     }
  }
};

class temp
{
public:
  void func1(int x)
  {
     cout << "inside func1" << endl;
  }

  bool func2()
  {
    cout << "inside func2" << endl;
    return true;
  }
};


int main()
{
  temp t;

  meta<10>()(t.func1, t.func2);  //not working, func1 and func2 are class member functions

//meta<10>()(func1, func2);   //working, if func1 and func2 are normal functions (not part of the class)
}

If you want to pass member functions as arguments, you can pass them as member function pointers, but you need to pass an object of that type to the function as well.如果您想将成员函数作为参数传递,您可以将它们作为成员函数指针传递,但您还需要将这种类型的对象传递给函数。 (If there's no object, there's no member function to call). (如果没有对象,则没有可调用的成员函数)。

Also, note that the syntax for calling the member function is different as well:另请注意,调用成员函数的语法也不同:

template <typename T>
void operator()(T &t, void (T::*f1)(int), bool (T::*f2)())
{
   if ((t.*f2)())  // call member functions like this
   {
     (t.*f1)(n);
   }
}

and now you can call the function this way:现在你可以这样调用函数:

meta<10>()(t, &temp::func1, &temp::func2); 

Here's a demo .这是一个演示

To call a member function you must have an object on which you call it.要调用成员函数,您必须有一个可以调用它的对象。 Your code does not work, because t is not passed to meta::operator() in any way.您的代码不起作用,因为t没有以任何方式传递给meta::operator() To solve the problem we will address this issue.为了解决这个问题,我们将解决这个问题。

The syntax in meta::operator() is f1(n) and f2() . meta::operator()的语法是f1(n)f2() Therefore F1 and F2 must be either因此F1F2必须是

  • function types, or函数类型,或
  • class types which have an operator() .具有operator()类类型。

To make this work, we will use the latter.为了完成这项工作,我们将使用后者。 In main let's store a pointer to t in an object, and for the class of that object we will make an operator() which will call the method on t .main让我们在一个对象中存储一个指向t的指针,对于该对象的类,我们将创建一个operator() ,它将调用t上的方法。 Like this:像这样:

struct caller1 {
  void operator()(int x) const { t->func1(x); }
  temp* t;
};

struct caller2 {
  bool operator()() const { return t->func2(); }
  temp* t;
};

int main()
{
  temp t;

  caller1 c1 { &t };
  caller2 c2 { &t };
  meta<10>()(c1, c2);
}

But with the C++ Standard Library it's even simpler.但是有了 C++ 标准库,它就更简单了。 You don't need to create classes like caller1 and caller2 .您不需要创建像caller1caller2这样的类。 You can usestd::bind in header functional ( live demo ):您可以在标头functional现场演示)中使用std::bind

int main()
{
  temp t;

  auto f1 = bind(&temp::func1, &t, placeholders::_1);
  auto f2 = bind(&temp::func2, &t);
  meta<10>()(f1, f2);
}

Passing &t to bind creates a class that stores a pointer to t .&t传递给bind会创建一个存储指向t的指针的类。 If for some reason you need to store a copy of t in f1 and f2 , pass t to bind .如果由于某种原因,你需要的副本存储tf1f2 ,通过tbind

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM