【问题标题】:Difference between void(*)() and void(&)() in C++ [duplicate]C ++中void(*)()和void(&)()之间的区别[重复]
【发布时间】:2015-05-31 18:18:21
【问题描述】:

在此示例代码中,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&amp; func2 = &amp;someFunc; 不会编译,而auto func1 = &amp;someFunc; 会。尽管在这种情况下使用auto 只会混淆差异。

标签: c++ pointers


【解决方案1】:

如果您希望能够将指针分配给函数,然后再更改该指针指向的内容,请使用auto fp = func。如果没有,请使用参考 auto&amp; 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;
}

【讨论】:

    【解决方案2】:
    auto func1 = someFunc; 
    auto& func2 = someFunc;
    

    假设你有另一个函数,你希望 func2 指向这个另一个函数

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

    所以你在下面做

    func2 = function();
    

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

    【讨论】:

      猜你喜欢
      • 2015-09-26
      • 2011-04-12
      • 1970-01-01
      • 2018-03-05
      • 2014-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多