在Bjarne Stroustrup的主页(C++ 11 FAQ)中:
struct X { int foo(int); };
std::function<int(X*, int)> f;
f = &X::foo; //pointer to member
X x;
int v = f(&x, 5); //call X::foo() for x with 5
Run Code Online (Sandbox Code Playgroud)
它是如何工作的?std :: function如何调用foo成员函数?
模板参数int(X*, int),是&X::foo从转换成员函数指针到一个非成员函数指针?!
(int(*)(X*, int))&X::foo //casting (int(X::*)(int) to (int(*)(X*, int))
Run Code Online (Sandbox Code Playgroud)
澄清:我知道我们不需要使用任何指针来使用std :: function,但我不知道std :: function的内部如何处理成员函数指针和非成员函数之间的这种不兼容性指针.我不知道标准如何允许我们实现像std :: function这样的东西!
我有一个指向函数的指针,假设有任何签名.我有5个不同的功能和相同的签名.
在运行时,其中一个被分配给指针,并调用该函数.
如果不在这些函数中插入任何print语句,我怎样才能知道指针当前指向的函数名称?
我有这段代码:
int foo() { return 0; }
int main()
{
int (*float_function)(float) = foo;
}
Run Code Online (Sandbox Code Playgroud)
x86-64 GCC 12.2当使用, with编译时-Wall,它会产生警告(链接):
警告:从不兼容的指针类型“int (*)()”初始化“int (*)(float)”[-Win兼容指针类型]
但是,当我从 更改float为double(链接)时:
int foo(){ return 0;}
int main()
{
int (*double_function)(double) = foo;
}
Run Code Online (Sandbox Code Playgroud)
现在警告消失了。
但我认为这两者都应该受到警告。
我有什么地方说错了吗?为什么 GCC 不抱怨第二个例子?
我在C中读到了函数指针.每个人都说这将使我的程序运行缓慢.这是真的吗?
我制作了一个程序来检查它.我在两个案例中得到了相同的结果.(衡量时间.)
那么,使用函数指针是不是很糟糕?提前致谢.
为了回应一些人.在循环中我比较的时候我说"运行缓慢".像这样:
int end = 1000;
int i = 0;
while (i < end) {
fp = func;
fp ();
}
Run Code Online (Sandbox Code Playgroud)
执行此操作时,如果执行此操作,我会得到相同的时间.
while (i < end) {
func ();
}
Run Code Online (Sandbox Code Playgroud)
所以我认为函数指针没有时间差异,也没有像许多人所说的那样使程序运行缓慢.
我尝试调用一个函数,该函数作为函数指针传递,没有参数,但我不能使它工作.
void *disconnectFunc;
void D::setDisconnectFunc(void (*func)){
disconnectFunc = func;
}
void D::disconnected(){
*disconnectFunc;
connected = false;
}
Run Code Online (Sandbox Code Playgroud) 考虑这两个功能:
void foo() {}
void bar() {}
Run Code Online (Sandbox Code Playgroud)
是保证&foo != &bar吗?
同样的,
template<class T> void foo() { }
Run Code Online (Sandbox Code Playgroud)
是保证&foo<int> != &foo<double>吗?
我知道折叠函数定义有两个连接器.
MSVC积极地COMDAT折叠函数,因此具有相同实现的两个函数可以转换为一个函数.作为副作用,这两个函数共享相同的地址.我的印象是这是非法的,但我无法找到标准中的哪些内容是非法的.
Gold链接器还可以折叠功能,包括a safe和all设置. safe意味着如果采用了一个功能地址,它就不会折叠,all即使采用了地址也会折叠.因此safe,如果函数具有不同的地址,则黄金的折叠表现为.
虽然折叠可能是意料之外的,并且存在依赖于具有不同地址的不同(相同实现)函数的代码(因此折叠可能是危险的),在当前的C++标准下它实际上是非法的吗?(此时为C++ 14)(自然如果safe折叠是合法的)
c++ function-pointers one-definition-rule language-lawyer comdat-folding
考虑这个javascript代码:
var bar = function () { alert("A"); }
var foo = bar;
bar = function () { alert("B"); };
foo();
Run Code Online (Sandbox Code Playgroud)
运行此代码时,我得到"A".这种行为是javascript规范的一部分吗?我可以依赖它吗?
我有点问题.我正在尝试动态定义一个函数指针数组calloc.但我不知道如何编写语法.非常感谢.
所以我想在制作函数指针时,你不需要operator &获取初始函数的地址:
#include <stdio.h>
double foo (double x){
return x*x;
}
int main () {
double (*fun1)(double) = &foo;
double (*fun2)(double) = foo;
printf("%f\n",fun1(10));
printf("%f\n",fun2(10));
printf("fun1 = %p \t &foo = %p\n",fun1, &foo);
printf("fun2 = %p \t foo = %p\n",fun2, foo);
int a[10];
printf(" a = %p \n &a = %p \n",a,&a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
>./a.out
100.000000
100.000000
fun1 = 0x4004f4 &foo = 0x4004f4
fun2 = 0x4004f4 foo = 0x4004f4
a = 0x7fff26804470
&a = 0x7fff26804470
Run Code Online (Sandbox Code Playgroud)
然后我意识到这对于数组也是如此,这意味着如果你有 …
有没有办法在ANSI C中打印指向函数的指针?当然这意味着你必须将函数指针强制转换为void指针,但似乎不可能?
#include <stdio.h>
int main() {
int (*funcptr)() = main;
printf("%p\n", (void* )funcptr);
printf("%p\n", (void* )main);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
$ gcc -ansi -pedantic -Wall test.c -o test
test.c:在函数'main'中:
test.c:6:警告:ISO C禁止将函数指针转换为对象指针类型
test.c:7:warning :ISO C禁止将函数指针转换为对象指针类型
$ ./test
0x400518
0x400518
它"工作",但非标准...