簡體   English   中英

將一種方法作為參數傳遞給另一種方法的可能性

[英]Possibility of passing a method as a parameter to another method

我正在學習c ++,我想知道是否可以將一個方法作為另一個方法的參數傳遞?

我想要做的事情大致概述如下:

void insertionSort() {
   //perform sort
}

int timeOfOperation(methodInQuestion) {
    // time 1
    methodInQuestion;
    //time 2
    return time2-time;
}

int main() {
   cout << timeOfOperation(insertionSort());
   return 0;
}

有沒有辦法做這樣的事情?

編輯:

我感謝您的答復。 我還有一個問題。 在我的實際代碼中,這都是在名為dataStructure的類中發生的,我正在其他地方創建它的實例並調用這些方法。

dataStructure ds();
ds.timeOperation(ds.insertionSort());

當我嘗試實施發布的一些解決方案時,出現此錯誤:

IntelliSense: no instance of function template
"dataStructure::timeOperation" matches the argument list argument
types are: (void) object type is: dataStructure

我不太了解為什么創建實例會影響這一點。 誰能解釋?

================================================== ===========

編輯2:

我將為此部分或多或少張貼我的確切代碼:

//main.cpp

#include "arrayList.h"
#include "arrayListStructure.h"
#include "Person.h"

using namespace std;

int main() {

    arrayList<Person> *al = new arrayList<Person>(length);
    arrayListStructure als(al);
    //als.fillStructure(data);
    als.timeOperation(als.insertionSort());

return 0;
}


//arrayListStructure.cpp

#include "arrayListStructure.h"
#include <functional>

double arrayListStructure::timeOperation(std::function<void()> operation) {...}
void arrayListStructure::insertionSort() {...}

arrayListStructure::arrayListStructure(arrayList<Person> *al)
{
this -> al = al;
}

還有更多,但我認為這是與問題有關的全部

是的,類似:

#include <functional>
#include <ctime>
#include <iostream>

void insertionSort() { /*...*/ }

std::clock_t timeOfOperation( std::function<void()> operation ) 
{
    const std::clock_t start = std::clock();
    operation();
    return std::clock() - start;
}

int main() 
{
    std::cout << timeOfOperation(insertionSort) << '\n';
}

由於您可能不想要全局數據(像insertSort這樣的無參數函數需要全局數據),因此您可以執行以下操作:

template<class Container>
void insertionSort( Container& c ) 
{ 
   /*sort the contents of c*/ 
}

現在,您必須傳遞要排序的數據。您可以使用std :: bind或更好的C ++ 11 lambdas進行此操作。 然后,如Yakk的回答所述,我們可以對計時器函數進行模板化,以便其本地接受std :: functions,lambda,functors(重載operator()的類)或函數指針:

template<class Operation>
std::clock_t timeOfOperation( Operation&& operation ) 
{/*...*/ }

這是完整的程序:

#include <functional>
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm> // for generate
#include <ctime> // for clock
#include <cstdlib> // for rand

template<class Container>
void insertionSort( Container& c ) 
{ 
   /*sort the contents of c*/ 
}

template<class Operation>
std::clock_t timeOfOperation( Operation&& operation ) // or just timeOfOperation( Operation&& operation )
{
    const std::clock_t start = std::clock();
    operation();
    return std::clock() - start;
}

int main() 
{
    std::vector<int> v( 100 );
    std::generate( v.begin(), v.end(), std::rand );
    auto op = [&]() { insertionSort( v ); };
    std::cout << timeOfOperation( op ) << '\n';
}

合並最后兩行(使用C ++ 11 lambda),如下所示:

std::cout << timeOfOperation( [&]() { insertionSort( v ); } ) << '\n';

但是,當然,在非作業代碼中,您應該使用內置的排序功能,而不要自己滾動。


關於更新:第一行實際上是函數定義,而不是類的實例:

dataStructure ds(); // function, not an instance!
ds.timeOperation(ds.insertionSort()); // insertionSort returns void. 
// Can't convert void to a template param that can be called with the () operator

在C ++中,規則是,如果可以將某些內容解釋為函數原型,那么它將是。 放下paretheses,您會沒事的:

dataStructure ds; // <-- note
ds.timeOperation(ds.insertionSort());

回答您的評論,只要不能將其解釋為原型,就可以了。 考慮:

struct S {};

struct dataStructure
{
   dataStructure() {}
   dataStructure(int) {}
   dataStructure(S) {}
   void go() {}
};

int main()
{
    dataStructure ds1 = dataStructure();
    dataStructure ds2(10);
    dataStructure ds3( S() ); 
    dataStructure ds4( (S()) ); // Extra parens clarify for the compiler


    ds1.go(); // Ok  
    ds2.go(); // Ok  
    ds3.go(); // Doh! ds3 is a function prototype
    ds4.go(); // Ok  
}

更新您的Edit 2:

更改此行:

als.timeOperation(als.insertionSort());

至:

als.timeOperation([&](){als.insertionSort()});

或(優先級較低,但如果沒有lambda):

als.timeOperation( std::bind( &arrayListStruction::insertionSort, als ) );

演示如何使用函數指針


演示:

#include <iostream>
using namespace std;

void insertionSort() {
   cout<<"insertion"<<endl;
}

int timeOfOperation(void(*sortFunc)(void)) {
   sortFunc();
   return 1;
}

int main() {
   cout << timeOfOperation(insertionSort);
   return 0;
}

看到這個演示

在安排操作的時間時,您需要盡可能少的開銷。

#include <functional>
#include <ctime>
#include <iostream>

void insertionSort() { /*...*/ }

template<typename F>
std::clock_t timeOfOperation( F&& operation ) {
  const std::clock_t start = std::clock();
  // time 1
  operation();
  //time 2
  return std::clock() - start;
}

int main() {
  std::cout << timeOfOperation(insertionSort) << '\n';
}

這是@metal的解決方案,但模板除外。 通過std::function調用函數的開銷很小。 不利的timeOfOperation是,我們必須將timeOfOperation的實現放入頭文件中。

timeOfOperation ,如果您的編譯器不支持C ++ 11,請將簽名中的&&放到timeOfOperation ,這是真正不需要的C ++功能。

如果您想對帶有狀態的多行代碼計時,可以這樣做:

void sort( int* buff, size_t count ) { /* ... */ }

int main() {
  enum { size_of_data = 10 };
  int data[size_of_data] = {1,2,3,4,5,6,-1,0};
  std::cout << timeOfOperation([&](){
    sort( &data[0], size_of_data );
  }) << '\n';
}

具有相同的timeOfOperation -我在其中寫的lambda作為模板函子傳入,然后在timeOfOperation內調用而timeOfOperation沒有開銷。

暫無
暫無

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

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