我编写了一个代码来传递函数指针列表(按其名称)作为参数。但我有错误。你能解释为什么我在做地图时有错误吗?
#include <functional>
#include <iostream>
#include <string>
#include <vector>
#include <map>
class Foo
{
public:
void foo(int a, int b)
{
std::cout << a <<" "<< b<<'\n';
}
};
class Bar
{
public:
void bar(int a, int b)
{
std::cout << a<<" "<< b << '\n';
}
};
int main()
{
Foo foo;
Bar bar;
std::map<std::string, void (*)(int,int)>myMap;
myMap["bar"] = &Bar::bar;
myMap["foo"] = &Foo::foo;
std::vector<std::function<void (int )>> listofName;
std::string s1("bar");
std::string s2("foo");
listofName.push_back(bind(myMap[s1],&bar,std::placeholders::_1,1));
listofName.push_back(bind(myMap[s2],&foo,std::placeholders::_1,3));
for (auto f : listofName) {
f(2);
}
return 0;
}
错误:
34:18:错误:无法将'void(Bar::)(int, int)'转换为'std::map, void(*)(int, int)
35:18:错误:无法将“无效(foo::)(整数,整数)”转换为“标准::映射,无效(*)(整数,整型)
41:70:错误:没有用于调用“std::vector”的匹配函数
成员函数包含指向this
的隐藏指针。一种古老的技术(继承自C)是将成员函数包装在一个静态函数中,该函数采用指向对象的指针。这里的好处是,由于可以安全地将任何指针强制转换为void*
,因此可以告诉静态包装器它的第一个参数是void*,并将其强制转换为正确的对象指针以使用它。当然,如果你传递一个指向不同对象的指针,你会得到未定义的行为。但它只需要对原始代码进行最小的更改:
#include <functional>
#include <iostream>
#include <string>
#include <vector>
#include <map>
class Foo
{
public:
void foo(int a, int b)
{
std::cout << a <<" "<< b<<'\n';
}
static void doFoo(void *obj, int a, int b) { // the wrapper
static_cast<Foo *>(obj)->foo(a, b);
}
};
class Bar
{
public:
void bar(int a, int b)
{
std::cout << a<<" "<< b << '\n';
}
static void doBar(void *obj, int a, int b) { // wrapper again
static_cast<Bar *>(obj)->bar(a, b);
}
};
using std::bind;
int main()
{
Foo foo;
Bar bar;
// function will take an additional void *
std::map<std::string, void (*)(void*, int,int)>myMap;
myMap["bar"] = &Bar::doBar;
myMap["foo"] = &Foo::doFoo;
std::vector<std::function<void (int )>> listofName;
std::string s1("bar");
std::string s2("foo");
listofName.push_back(bind(myMap[s1],(void *)&bar,std::placeholders::_1,1));
listofName.push_back(bind(myMap[s2],(void *)&foo,std::placeholders::_1,3));
for (auto f : listofName) {
f(2);
}
return 0;
}
这样,它编译得很好(在C 11模式下),并按预期给出:
2 1
2 3
不能在这样的映射中存储成员函数指针:
std::map<std::string, void (*)(int,int)>myMap;
您必须将其更改为:
std::map<std::string, void (Foo::*)(int,int)>myMap;
但是你只能存储指向Foo类成员的指针。所以最好的选择是在这里使用d::f。下面是一个工作代码:
直播
#include <functional>
#include <iostream>
#include <string>
#include <vector>
#include <map>
class Foo
{
public:
void foo(int a, int b)
{
std::cout << a <<" "<< b<<'\n';
}
};
class Bar
{
public:
void bar(int a, int b)
{
std::cout << a<<" "<< b << '\n';
}
};
int main()
{
Foo foo;
Bar bar;
using namespace std::placeholders;
std::map<std::string, std::function<void (int,int)>>myMap;
myMap["bar"] = std::bind(&Bar::bar, &bar, _1, _2);
myMap["foo"] = std::bind(&Foo::foo, &foo, _1, _2);
std::vector<std::function<void (int )>> listofName;
std::string s1("bar");
std::string s2("foo");
listofName.push_back(bind(myMap[s1], std::placeholders::_1, 1));
listofName.push_back(bind(myMap[s2], std::placeholders::_1, 3));
for (auto f : listofName) {
f(2);
}
return 0;
}
成员函数需要知道它们是哪个对象的成员,这样它们才能对正确的< code>this进行操作。
因此,您需要确保存储在map中的函数知道它将来是哪个对象的成员。
int main() {
using namespace std::placeholders;
Foo foo;
Bar bar;
std::map<std::string, std::function<void(int, int)>> myMap;
myMap["bar"] = std::bind(&Bar::bar, &bar, _1, _2);
myMap["foo"] = std::bind(&Foo::foo, &foo, _1, _2);
稍后,它已经知道它是哪个对象的成员,你不需要再告诉它了:
// ..
listofName.push_back(std::bind(myMap[s1], _1, 1));
listofName.push_back(std::bind(myMap[s2], _1, 3));
C++ 指针 C++ 允许您传递指针给函数,只需要简单地声明函数参数为指针类型即可。 下面的实例中,我们传递一个无符号的 long 型指针给函数,并在函数内改变这个值: #include <iostream> #include <ctime> using namespace std; void getSeconds(unsigned long *par); int main () {
我正在尝试将参数传递给作为参数传递的函数指针。 代码: 我得到了这个错误: 类型"void"的参数与类型"void(*)(wchar_t*,wchar_t*)"的参数不兼容 如何解决此问题以完成我想要实现的目标? 编辑:对不起,不清楚。我实际上试图完成的是将函数注入子进程并传递两个参数(wchar_t*、wchar_t*),以便我可以使用它们。但主函数可以是void或int argc、char**
我正在尝试设置一个“事件接收器”类,将GLFW回调封装到用户可以从中继承的类中,但在将基类成员函数传递到GLFW“set callback”函数中时遇到问题。 这本质上提供了一个带有纯虚拟函数的基类,供用户继承和重写,以便在事件发生时提供自己的逻辑。用户定义的子类将被传递到更大的“应用程序框架”类中,该类将进行必要的调用以设置GLFW回调函数。 当然,您不能将成员函数作为函数参数传递,因为您必须提
C ++允许您传递指向函数的指针。 为此,只需将函数参数声明为指针类型即可。 下面是一个简单的例子,我们将一个无符号长指针传递给一个函数并更改函数内部的值,该函数反映在调用函数中 - #include <iostream> #include <ctime> using namespace std; void getSeconds(unsigned long *par); int main () {
FAQs in section [33]: [33.1] “成员函数指针”类型不同于“函数指针”吗? [33.2] 如何将一个成员函数指针传递到信号处理函数,X事件回调函数,系统调用来启动一个线程/任务等? [33.3] 为什么我总是收到编译错误(类型不匹配)当我尝试用一个成员函数作为中断服务例程? when I try to use a member function as an interru
一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似。我们可以把函数的这个首地址(或称入口地址)赋予一个 指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。这种指针就是 函数指针。 函数指针的定义形式为: returnType (*pointerName)(param list); returnType