[英]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.