"void (*)(int)"与"void (^)(int)"相同吗?
Does 'void (*)(int)' the same with 'void (^)(int)'?
今天,我正在处理从C++到Objective-C方法的回调传递
最后,我计算出了它,但有几个代码让我感到困惑。
在Objective-c中,人们通常使用块来实现回调,块声明如下:
returnType(^blockName)(parameterTypes)
我还学习了C++回调,一个定义如下的相同类型的回调:
returnType(*funcName)(parameterTypes)
当我从C++向Objective-C传递回调时,编译器警告我:
"无法用'void(*)(int)'类型的右值初始化'void(^)(int
最后,我将^
更改为*
,它起作用了。我想知道,^
和*
在定义上有什么区别,它们有相同的行为吗?
这是一个块:
returnType (^blockName)(parameterTypes)
这是一个函数指针:
returnType (*funcName)(parameterTypes)
它们不兼容。
标准C和C++没有可调用的块。然而,显然,这些语言的一些编译器确实将该功能作为扩展来实现。我看到的一些文档表明,这也是苹果对Objective C的扩展,但由于Objective C在苹果世界之外很少使用,这可能是一个没有区别的区别。
在任何语言中,如果你将回调实现为函数,那么你必须通过函数指针将该回调呈现给预期的调用者,调用者必须准备好以这种形式接受它。另一方面,如果你以块的形式实现回调,那么你必须通过块指针将其呈现给调用者,并且调用者必须准备好接受形式的。这两者是不可互换的,而且它们有不同的语法,正如您所展示的那样。不过,可以设计一种机制,通过单独的参数或完全独立的登记职能,接受这两种形式。
Objective-C块(^
)与函数指针(*
)不兼容
与函数指针相比,它们的优点是能够从周围的上下文中捕获值和变量(它们是闭包)。
编写一个从块调用函数指针的包装器很容易:
typedef int (*funptr)(int);
typedef int (^funblock)(int);
int use_block_callback(int y, funblock fb)
{
return fb(y);
}
int use_funptr_callback(int y, funptr f)
{
return use_block_callback(y, ^ int (int x) { return f(x); });
}
int add_one(int x) { return x + 1; }
int foo(int x)
{
return use_funptr_callback(23, add_one);
}
// Or
int (*some_pointer)(int) = add_one;
int (^some_block)(int) = ^ int (int x) { return some_pointer(x); }
(关于块的"用Objective-C编程"。)
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- 为什么 c++ 中的 main() 函数不采用除 int 和 void 之外的任何其他返回类型
- 不能使这种类型的"void(C::* volatile)(int) const "在参考手册C++示
- 如何使模板函数像 R f<void(int)>(args...)
- template<class T, int N> void h(T const(&)[N]); as friend function
- 函数 LNK2019 "int __cdecl __scrt_common_main_seh(void)" 中引用的未解析外部符号主错误 (?__scrt_common_main_seh@@YAHXZ
- 从不兼容的类型 'void (Button::*)(int)' 分配给'void (*)(int)'
- 错误 C2084:函数"int main(void)"已具有主体
- 编译Qt项目给出了对运算符delete(void*,unsigned int)的未定义引用
- int main(void) 在 C++ 中有效吗?
- sqlite3 更改函数回调参数 void* not用于 int* C++
- 什么是 qsort void*x 和 *(int*)x?
- 无法将参数 1 从"int (__thiscall A::* *)(void)"转换为"int (__cdecl *)(void)"
- 需要获取 void 或 int 的 Cpp 模板函子
- 为什么我可以将 void* static_cast 到 int* 而不是 int*&?
- 您如何通过函数的void指针将int值传递,然后将其转换回int值
- x = malloc(n * sizeof (int));无法将 void 转换为 int
- 错误:从"int (*)(std::list<myclass*>, int, char**, char**)"到"int (*)(void*, int, char**, char**)"的
- 如何在c++中将数组char复制到字符串或int*(void*)中