【问题标题】:Functions and function pointers in C++C++中的函数和函数指针
【发布时间】:2016-02-03 17:23:39
【问题描述】:

参考以下代码

#include <iostream>
using std::cout;
using std::endl;
#include <vector>
using std::vector;

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

int main() {
    vector<void (*) ()> functions;
    functions.push_back(function);         // (1) no error
    functions.push_back(&function);        // (2) no error
    for (const auto& func : functions) {
        func();
    }

    // vector<decltype(function)> vec;     // (3) error
    return 0;
}

当我取消注释 (3) 时似乎有一个错误,我只是想了解这背后的原因。当我将函数作为参数传递给模板化函数时,它是否将类型解析为函数指针?编译器将所有函数类型推断为函数指针是有意义的,但为什么 decltype() 不能解析为函数指针?

【问题讨论】:

  • 我没有答案,但我建议使用std::function 而不是函数指针。它更具可读性,你不用处理它是否是指针。
  • @AdiLevin std::function 只应在必要时使用,即当人们真正想要存储(!)没有任何共同之处但可调用的可调用对象时(使用各自的参数,返回各自的类型)。它增加了很多开销。

标签: c++ function templates c++11 function-pointers


【解决方案1】:

decltype(function)void() - 一个函数。
您需要的是函数的衰减版本 - void(*)():

std::decay<decltype(function)>::type

std::vector < std::decay<decltype(function)>::type > myPtrFunctionVec;

附言。
如果您正在使用 VC++(视觉标准输入输出),您可以通过打印 typeid(decltype(XXX)).name() 轻松查看从 decltype 推导出的类型。与其他编译器不同,VC++ 给出了未修饰的类型名称。对于元编程调试非常方便。

编辑:
正如@Daniel Jour 评论的那样,解决方案decltype(&amp;function) 也很有效,因为构造&amp;f 提供了指向f 的指针,这正是您所需要的

【讨论】:

  • std::decay 是个好主意,没想到。你也可以decltype(&amp;function):ideone.com/Af98uJ
  • @DanielJour 酷!我不知道那个表达式会产生一个指向函数的指针!
  • @DavidHaim 我也不是。这是您认为行不通的事情之一,直到您再次查看它并意识到它非常有意义。 &amp;function 是一个函数指针,因此在逻辑上将它传递给 decltype 将评估为函数指针的类型。不过,这太简单了,不明显。
  • 这些函数作为汇编指令位于内存中的其他位置,您不能将其存储在向量中。您可以存储的是指向将初始化对汇编指令的调用的指针。你不能存储函数,只有指向函数的指针
  • 嗯,从技术上讲,如果您编写 JIT 编译器,您可以,但这是完全不同的说法
猜你喜欢
  • 2018-09-12
  • 2011-01-07
  • 2016-09-07
  • 1970-01-01
  • 2016-03-14
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多