[英]What difference between void(void) and void(*)(void)?
void(*)(void)
是一个函数指针,而我认为void(void)
也是一种表示函数类型的方法。 它在std::function
<functional> 中用作模板参数
什么是void(void)
以及它与void(*)(void)
有何不同?
什么是
void(void)
以及它与void(*)(void)
有何不同?
它们是不同的类型。 尽管在许多情况下前者( void(void)
)可以隐式转换为后者( void(*)(void)
)。
void(void)
类型称为函数类型。 以下也是函数类型:
int (int, int) //this is a function type
void(int) //this is a function type as well
另一方面, void (*)(void)
是指向函数类型的指针。 也就是说,它是一个指针,指向一个参数为0
且返回类型为void
的函数。
void(void)
是函数类型的规范,它是签名。void(*)(void)
是指向函数的指针。这些是不同的。
首先,让我们先说,有时void(void)
将被自动视为指向函数的指针(即在参数列表中)。 我们仍然可以显式地使用void(*)(void)
,但void(void)
在这些情况下将是等价的。
// Here, we explicitly state that the f is a pointer to function
void foo(void (*f)(void), int i);
// Equivalent, f is automatically treated as a pointer to the function
void foo(void f(void), int i);
例如,提到的std::function
就不是这种情况。 两者的类型不同,但可能具有相似的行为(即我们可以在指向函数的指针上使用函数调用运算符)。
void bar();
// Prints 1
std::cout << std::is_same<void(void), decltype(bar)>::value << '\n';
// Prints 1 as well
// Note the pointer type specifier
std::cout << std::is_same<void(*)(void), decltype(bar)*>::value << '\n';
// Prints 0
// Note the absence of the pointer type specifier
std::cout << std::is_same<void(*)(void), decltype(bar)>::value << '\n';
特别是:
// Ok
std::function<decltype(bar)> fn1 = bar;
// error: variable ‘std::function<void (*)()> fn2’ has initializer but incomplete type
std::function<decltype(bar)*> fn2 = bar;
请注意,我们可以在std::function
中“存储”一个指向成员函数的指针,但即便如此,模板的参数仍然不是指向函数类型的指针,而是一个普通的函数签名。
struct MyType {
void func(int) {}
};
int main() {
// Note, we can't have a member function without an instance of the type
// Thus we specify the usually implicit first param and the explicit int param
std::function<void(MyType&, int)> fn_mem = &MyType::func;
MyType my_object;
fn_mem(my_object, 21);
}
有关std::function
的更多信息,请参阅 参考资料。 简而言之,使用std::function
代替函数指针与使用智能指针代替原始指针具有相同的 moto。
您可能想知道void(void)
或int(int)
样式函数类型规范的其他用途,所以这是您可能经常看到的另一个示例:
using func_t = int(int);
// func_ptr_func return a pointer to the func_t type alias
func_t* func_ptr_func();
注意与参数不同,编译器不会将返回中的函数类型视为指向函数类型的指针。 因此,我们必须在返回的情况下显式指定指针类型。
// Here, baz is a function that doesn't take any agruments
// And returns a pointer to a function that takes an int argument and "returns" void
void (*baz())(int);
对于void fun(){}
, std::is_same_v<void(void)>, decltype(fun)>
为真; 并且std::is_same_v<void(*)(void)>, decltype(&fun)>
为真。 事实上,这些才是他们真正的类型。 但是,标准允许您将类型为void(void)
的对象隐式转换为void(*)(void)
(因此您甚至可以编写(******funptr)()
),这就是我们总是混淆它们的原因.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.