我想创建具有函数指针作为参数的函数。
#include <iostream>
using namespace std;
class test{
public:
test(){};
double tt(double input){
return input;
};
};
double fptr_test(double (*fptr)(double), double input){
return fptr(input);
}
int main(){
test t;
cout << t.tt(3) << endl;
cout << fptr_test(t.tt, 3) << endl; // This line doesn't work
cout << fptr_test(&test::tt, 3) << endl; // This line can't compile
return 1;
}
但它不起作用。 我怎么能把类成员函数作为参数传递?
我可以在没有实例化的情况下调用成员函数吗?
答案 0 :(得分:4)
如果要将指针传递给成员函数,则需要使用成员函数指针,而不是通用自由函数的指针和调用它的对象。
两者都不是可选的。
double fptr_test(test& t, double (test::*fptr)(double), double input){
return t.*fptr(input);
}
// call like this:
fptr_test(&test::tt, 3); // Your second try
答案 1 :(得分:3)
函数指针和成员函数指针具有不兼容的类型。例如,&test::tt
的类型是
double (test::*)(double)
而不是
double (*)(double)
这种差异的原因是[非static
]成员函数有一个隐藏参数:指向成员函数的对象的指针,即this
。从成员函数中传出正常函数指针的方法是通过提供this
指针的函数进行委托,因此需要额外的参数。
在C ++中,不将函数指针作为函数的参数更有用,函数可以由函数自定义,而是采用函数对象。这种方法有两种形式:
快速方法是使函数对象类型成为模板参数,并直接传递您获得的任何函数对象。例如,您fptr_test()
看起来像这样:
template <typename Fun>
double fptr_test(Fun fun, double input) {
return fun(input);
}
使用的隐式概念是一个可调用double
参数的函数,其结果可转换为double
。
特别是当被调用的函数需要单独编译时,对每种函数对象使用模板是不可行的。在这种情况下,使用类型擦除表示更合理,即std::function<...>
,例如:
double fptr_test(std::function<double(double)> fun, double input) {
return fun(input);
}
在这两种情况下,函数对象只接受一个参数,而您的成员函数接受两个:调用函数的对象和double
参数。你是std::bind(...)
对象的第一个参数,并将结果对象传递给fptr_test()
:
test object;
std::cout << fptr_test(std:bind(&test::tt, &object, std::placeholders::_1), 3) << '\n';
std::cout << fptr_test([&](double input){ return object.tt(input); }, 3) << '\n';
代码使用两种不同的方法来绑定对象:第一种使用std::bind()
而第二种使用lambda函数。这两个调用都应该与fptr_test()
提供的两个实现一起使用。
答案 2 :(得分:1)
你可能想要的是:
#include <iostream>
#include <functional>
using namespace std;
class test{
public:
test(){};
double tt(double input){
return input;
};
};
double fptr_test( std::function<double(double)> func, double input){
return func(input);
}
int main(){
using namespace std::placeholders;
test t;
cout << t.tt(3) << endl;
cout << fptr_test( std::bind( &test::tt, t, _1 ), 3) << endl;
return 0;
}
顺便说一句 - 当你的程序正确完成时,你想从main()
答案 3 :(得分:0)
以下是修改后的代码。
#include <iostream>
using namespace std;
class test{
public:
test(){};
double tt(double input){
return input;
};
};
double fptr_test(test* t, double (test::*fptr)(double), double input){
return (t->*fptr)(input);
}
int main(){
test t;
cout << t.tt(3) << endl;
cout << fptr_test(&t, &test::tt, 3) << endl;
return 1;
}