函数指针和返回类型转换

fre*_*low 5 c++ templates function-pointers type-conversion c++11

假设我有一个执行一些副作用的函数,然后返回一个答案:

int foo()
{
    perform_some_side_effect();
    return 42;
}
Run Code Online (Sandbox Code Playgroud)

我想绑定foo到一个函数指针,但我对答案不感兴趣,只是副作用:

void (*bar)() = foo;
Run Code Online (Sandbox Code Playgroud)

但是,这似乎是一个类型错误:

error: invalid conversion from ‘int (*)()’ to ‘void (*)()’
Run Code Online (Sandbox Code Playgroud)

这个错误背后的理由是什么?为什么类型系统不允许我忽略答案?


另外,如果我将函数指针包装在std::function:

std::function<void()> baz = foo;
Run Code Online (Sandbox Code Playgroud)

std::function(显然)如何设法绕过类型系统中的这种限制?

Dav*_*eas 9

这个错误背后的理由是什么?为什么类型系统不允许我忽略答案?

原因是类型不同,并且在调用地(通过函数指针)生成的代码是不同的.考虑一个调用约定,其中所有参数都写入堆栈,返回值的空间也保留在堆栈中.如果呼叫经过一个void (*)()那么没有空间将在堆栈中的返回值被保留,但功能(不知道它是如何被调用)仍然将写入42到调用者应该预留空间中的位置.

std :: function(显然)如何设法绕过类型系统中的这种限制?

它不是.它创建了一个函数对象,它将调用包装到实际函数中.它将包含一个成员,如:

void operator()() const {
   foo();
}
Run Code Online (Sandbox Code Playgroud)

现在,当编译器处理foo对它的调用时,知道它需要做什么来调用一个返回a的函数,int它将根据调用约定执行此操作.因为模板没有返回,所以它只会忽略实际返回的值.