我正在学习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;
}
还有更多,但我认为这与问题有关
答案 0 :(得分:2)
是的,比如:
#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,lambdas,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 lambdas)组合在一起:
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 ++中,规则是,如果可以将某些东西解释为函数原型,那么它就是。放下一些便利,你会没事的:
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
}
更新您的编辑2:
更改此行:
als.timeOperation(als.insertionSort());
为:
als.timeOperation([&](){als.insertionSort()});
或(不太喜欢,但如果你没有lambda):
als.timeOperation( std::bind( &arrayListStruction::insertionSort, als ) );
答案 1 :(得分:2)
演示如何使用函数指针
#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;
}
请参阅 this demo 。
答案 2 :(得分:2)
在计算操作时,您希望尽可能减少开销。
#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
的实现放入头文件中。
顺便说一句,如果您的编译器不支持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
内调用,旁边没有开销。