C++中 void(*)() 和 void(&)() 的区别

Difference between void(*)() and void(&)() in C++

本文关键字:void 区别 C++      更新时间:2023-10-16

在本示例代码中,func1void (*)(int, double)的类型,funkyvoid(&)(int, double)的类型。

#include <iostream>
using namespace std;
void someFunc(int i, double j) {
    cout << i << ":" << j << endl;
} 
int main(int argc, char *argv[]) {
    auto func1 = someFunc; 
    auto& func2 = someFunc;
    cout << typeid(func1).name() << endl;
    cout << typeid(func2).name() << endl;
    func1(10, 20.0);
    func2(10, 30.0);
}

输出显示差异:

PFvidE
FvidE
10:20
10:30

实际上,这两种类型之间有什么区别?

如果您希望能够为函数分配指针,然后稍后更改指针指向的内容,则使用auto fp = func。如果没有,则使用参考auto& rp = func,因为您无法重新分配它:

#include <iostream>
using namespace std;
int funcA(int i, int j) {
    return i+j;
}
int funcB(int i, int j) {
    return i*j;
}
int main(int argc, char *argv[]) {
    auto fp = funcA;
    auto& rp = funcA;
    cout << fp(1, 2) << endl; // 3 (1 + 2)
    cout << rp(1, 2) << endl; // 3 (1 + 2)
    fp = funcB;
    //rp = funcB; // error: assignment of read-only reference 'rp'
    cout << fp(1, 2) << endl; // 2 (1 * 2)
    return 0;
}

我试图想出一个更实际的例子来说明为什么任何人都会这样做,下面是一些使用指针数组根据用户输入调用函数的代码(arr的任何元素也可以在运行时更改以指向另一个函数(:

#include <iostream>
using namespace std;
void funcA(int i, int j) {
    std::cout << "0: " << i << ", " << j << endl;
}
void funcB(int i, int j) {
    std::cout << "1: " << i << ", " << j << endl;
}
void funcC(int i, int j) {
    std::cout << "2: " << i << ", " << j << endl;
}
int main(int argc, char *argv[]) {
    if (argc < 2) {
        cout << "Usage: ./a.out <val>" << endl;
        exit(0);
    }
    int index = atoi(argv[1]);
    if (index < 0 || index > 2) {
        cout << "Out of bounds" << endl;
        exit(0);
    }
    void(* arr[])(int, int) = { funcA, funcB, funcC };
    arr[index](1, 2);
    return 0;
}
auto func1 = someFunc; 
auto& func2 = someFunc;

假设你有另一个函数,你想让func2指向另一个函数

void function()
{
    cout<<"Hello world"<<endl;
}

所以你在下面做

func2 = function();

你得到的只是编译错误。func2的原因是引用,一旦初始化引用,就不能更改。