简体   繁体   中英

What difference between void(void) and void(*)(void)?

void(*)(void) is a function pointer while I suppose void(void) is also a way to represent function type. It is used as template parameter in std::function <functional>

What is void(void) and how it is different from void(*)(void) ?

What is void(void) and how it is different from void(*)(void) ?

They are distinct types . Although the former( void(void) ) can be implicitly converted to the latter( void(*)(void) ) in many contexts.

The type void(void) is called a function type . The following are also function types:

int (int, int) //this is a function type
void(int)      //this is a function type as well

On the other hand, void (*)(void) is a pointer to a function type . That is, it is a pointer that points to a function with 0 parameters and return type of void .

TL;DR

  • The void(void) is a specification of a function type, it's signature.
  • The void(*)(void) is a pointer to function.

These are distinct.


First, let's start by saying, that sometimes the void(void) will be automatically treated as a pointer to function (ie in a parameter list). We still can be explicit and use the void(*)(void) , but the void(void) will be an equivalent in these cases.

// 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);

This will not be the case for the mentioned std::function for example. The types of the two are different , yet may have similar behavior (ie we can use the function call operator on a pointer to 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';

And particularly:

// Ok
std::function<decltype(bar)> fn1 = bar;
// error: variable ‘std::function<void (*)()> fn2’ has initializer but incomplete type
std::function<decltype(bar)*> fn2 = bar;

Note, that we can however "store" a pointer to a member function in std::function , but even then the template's parameter still won't be of a pointer to function type, but a plain function signature.

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);
    
}

For more on std::function please refer to the reference . In short, the use of the std::function instead of the function pointers has the same moto as using the smart pointers instead of the raw pointers.

You may wonder on other uses of the void(void) or int(int) style function type specifications, so here's another example you may see often:

using func_t = int(int);
// func_ptr_func return a pointer to the func_t type alias
func_t* func_ptr_func();

NB unlike in the case of a parameter, the compiler won't treat the function type in a return as a pointer to function type. Thus, we must explicitly specify the pointer type in case of the return.

// 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);

for void fun(){} , std::is_same_v<void(void)>, decltype(fun)> is true; and std::is_same_v<void(*)(void)>, decltype(&fun)> is true. In fact, those are their real types. However, the standard approve you convert an object that has type void(void) to void(*)(void) implicitly (so you can even write (******funptr)() ), that's why we always confuse them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM