我希望能够在struct或class中存储函数的指针,那么当按下按钮时可以调用该函数吗?这就是我所拥有的:
struct INFO
{
std::function<int(int, int)> call_back;
};
class YO
{
public:
YO() {};
~YO() {};
int SUM(int A, int B) { return A + B; }
};
int main()
{
//std::function<int(int, int)> datFunc = SUM;
INFO info;
YO* yo = new YO();
info.call_back = yo->SUM;
//std::function<int(int, int)> func =;
std::cout << info.call_back(10, 10) << std::endl;
system("pause");
return 0;
}
我收到错误消息:
Error C3867 'YO::SUM': non-standard syntax; use '&' to create a pointer to member FunctionPointertest
Error C2679 binary '=': no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion) FunctionPointertest
答案 0 :(得分:1)
在这种情况下,您还需要向函数调用提供主机对象的实例。 std :: function支持此功能,它可以执行许多转换,但是原型变为
auth.requires_membership
当您调用它时:
std::function<int(YO*, int, int)> call_back;
答案 1 :(得分:0)
一些选项可以满足您的需求。使用lambda是最好的解决方案。
void func() {
INFO info;
YO yo;
YO* yo2 = new YO;
info.call_back = [&yo](int a, int b) {
return yo.SUM(a, b);
};
using namespace std::placeholders;
info.call_back = std::bind(&YO::SUM, std::ref(yo), _1, _2);
info.call_back = std::bind(&YO::SUM, yo2, _1, _2);
}
P.S。您通常不想在c ++中使用new
。
答案 2 :(得分:0)
这是Variadic
Template
Classes
的集合,如果您有C++17
可用,则可以轻松完成此操作。第一类仅存储任何类型的std::function
的通用版本!第二类通过member function
存储第一类,并且将register
,function pointer
,function object
或lambda
member function
存储。它还有另一个invoke
。在此示例中,我目前正在使用lambdas
。我有两个lambdas
,第一个1 st 接受两个int
类型,将它们相加并返回int
,如您在上面的问题中所述。 2 nd 将两个std::strings
连接起来,然后将它们打印到屏幕上,但不返回任何值。您甚至可以通过将std::vector<Functor<>>
存储在驱动程序类中来扩展它。 register_callback
在将其推入向量中时会略有变化,并且call_back
您可以选择。您可以一次全部调用它们,也可以通过索引值进行搜索以调用特定的索引,但是我将其作为练习留给您。
#include <string>
#include <iostream>
#include <functional>
template<typename RES_TYPE, typename... ARG_TYPES>
struct Functor {
std::function<RES_TYPE( ARG_TYPES... )> func_;
};
template<typename RES_TYPE, typename... ARG_TYPES>
class Driver {
private:
Functor<RES_TYPE, ARG_TYPES...> functor;
public:
Driver() = default;
~Driver() = default;
void register_callback( const Functor<RES_TYPE, ARG_TYPES...> &func ) {
functor = func;
}
RES_TYPE call_back( ARG_TYPES... args ) {
return functor.func_( std::forward<ARG_TYPES>(args)... );
}
};
int main() {
// Function Type: int ( int, int );
Functor<int, int, int> func;
auto lambda = []( int a, int b ) { return a + b; };
func.func_ = lambda;
Driver<int, int, int> driver;
driver.register_callback( func );
int a = 3;
int b = 5;
std::cout << driver.call_back( a, b ) << '\n';
std::cout << driver.call_back( 7, 5 ) << '\n';
// Function Type: void ( string, string );
Functor<void, std::string, std::string> func2;
auto lambda2 = []( std::string str1, std::string str2 ) {
str1 = str1 + " " + str2;
std::cout << str1 << '\n';
};
Driver <void, std::string, std::string> driver2;
func2.func_ = lambda2;
driver2.register_callback( func2 );
std::string str1 = "Hello";
std::string str2 = "World";
driver2.call_back( str1, str2 );
driver2.call_back( "Generic", "Programming" );
return 0;
}
输出为:
8
12
Hello World
Generic Programming
如果您在此处注意到此代码;无需弄乱指针或动态内存。通过为我们使用std::function
和类的默认dtors
可以解决所有这些问题。
我尽了最大的努力来设计这种具有简单性,可读性的产品,同时使其尽可能地便携和通用。我相信可以进行一些改进,但是我认为这符合您的要求。