簡體   English   中英

將member-function作為參數傳遞給function-template

[英]passing member-function as argument to function-template

考慮在c ++中實現例程的三種方法:通過仿函數,成員函數和非成員函數。 例如,

#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

class FOO
{
public:
  void operator() (string word)         // first: functor
  {
    cout << word << endl;
  }

  void m_function(string word)          // second: member-function
  {
    cout << word << endl;
  }
} FUNCTOR;


void function(string word)              // third: non-member function
{
  cout << word << endl;
}

現在考慮一個模板函數來調用上面的三個函數:

template<class T>
void eval(T fun)
{
  fun("Using an external function");
}

通過eval調用FOO::m_function的正確方法是什么? 我試過了:

FUNCTOR("Normal call");               // OK: call to ‘void FOO::operator()(string)‘
eval(FUNCTOR);                        // OK: instantiation of ‘void eval(T) [with T = FOO]’

function("Normal call");              // OK: call to ‘void function(string)’
eval(function);                       // OK: instantiation of ‘void eval(T) [with T = void (*)(string)]’

FUNCTOR.m_function("Normal call");    // OK: call to member-function ‘FOO::m_function(string)’
eval(FUNCTOR.m_function);             // ERROR: cannot convert ‘FOO::m_function’ from type
                                      //        ‘void (FOO::)(std::string) {aka void (FOO::)(string)}’
                                      //        to type ‘void (FOO::*)(std::basic_string<char>)’
                                      // In instantiation of ‘void eval(T) [with T = void (FOO::*)(string)]’:
                                      // ERROR: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘fun (...)’, e.g. ‘(... ->* fun) (...)’

指向成員函數的指針和指向函數的指針是兩種不同的動物。 前者采用隱式的第一個參數,即this指針,或者換句話說,指向要在其上調用成員函數的實例的指針。

通常,為了能夠將成員函數作為可調用對象傳遞,您可以bind要在其上調用它的實例,然后使用placeholders來指示稍后將傳遞給可調用對象的參數。 在你的情況下

eval(std::bind(&FOO::m_function, &FUNCTOR, std::placeholders::_1));

上面bind的第一個參數是指向要調用的成員函數的指針,第二個是指向要調用m_functionFOO實例的指針。 最后一個是占位符,指示在調用成員函數時應使用傳遞給bind創建的可調用對象的第一個參數。

另一種方法是將lambda表達式傳遞給eval ,該表達式采用char const * (或std::string const& )參數並調用成員函數。

eval([](char const *c) { FUNCTOR.m_function(c); });

現場演示

eval ,你不能調用成員函數,因為你沒有任何對象;

你可以這樣做:

template<class T, class U>
void eval(T&& object, U fun)
{
    (object.*fun)("Using an external function");
}

接着

eval(FUNCTOR, &FOO::m_function);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM