传递给 std::function 模板的模板参数究竟代表了什么?

Fur*_*ish 3 c++ function-pointers std-function

std::function它本身提供了一个很好的实用程序——它提供了类型擦除,以便一般地存储/提供对可调用项的访问。它的灵活性非常好:

#include <functional>
#include <iostream>

void printer() {
    std::cout << "I print!";
}

int adder(int a, int b) {
    return a + b;
}

int main() {
    std::function<void()> fun1 = printer;       // fun1() calls printer()
    std::function<int(int, int)> fun2 = adder;  // fun2(1, 2) calls adder(1, 2)

    std::function<void()> fun3 = [](){};        // fun3() will do nothing - same for the lambda
    std::function<int(int, int)> fun4 =
            [](int a, int b) { return a + b; }; // fun4(1, 2) will yield the sum
}
Run Code Online (Sandbox Code Playgroud)

而且,老实说,一切都说得通。std::function<void()>说它是 a function,它在被调用时返回void并且不接受 ( ()) 参数。同上std::function<int(int, int)>- 调用时,它返回 anint并需要两个ints 作为其参数。

虽然直觉,我相信我缺乏的是基本的了解究竟明确的模板参数。究竟是什么void()int(int, int)?它们不能是函数指针,因为当我这样做时:

int main() {
    using type = void();

    type x = printer;
}
Run Code Online (Sandbox Code Playgroud)

我收到以下警告和错误:

main.cpp:15:10: warning: declaration of 'void x()' has 'extern' and is initialized
 type x = printer;
      ^
main.cpp:15:14: error: function 'void x()' is initialized like a variable
 type x = printer;
          ^~~~~~~
Run Code Online (Sandbox Code Playgroud)

好吧,显然它看起来像一个变量——我希望它是一个变量。但是,如果我想要一个函数指针,我将不得不这样做:

using type = void(*)();
Run Code Online (Sandbox Code Playgroud)

代替:

using type = void();
Run Code Online (Sandbox Code Playgroud)

省略的类型究竟是什么*?例如,当与std::function?一起使用时,直观的显式模板参数究竟表示什么?

Nic*_*las 5

省略 * 的类型究竟是什么?

想想看。“后跟”a 的*类型意味着“指向该类型的指针”。如果您不使用 a “跟随”类型*,则该类型仅表示该类型。所以如果你有一个函数指针,那么它就是一个指向……一个函数类型的指针。

因此,类型 likevoid()是函数类型。

函数类型不同于对象类型,但它们仍然是类型。因此,您可以使用 C++ 允许的大多数基于类型的游戏。但由于它们不是对象类型,因此您不能创建函数类型的对象。

  • @Fuleeish更准确地说,括号并不像数学表达式中那样对术语进行“分组”。它们在这里的使用方式与声明或调用函数时相同,用于分隔函数参数列表。 (3认同)
  • @HTNW 这听起来像是为了“std::function”而将这种类型放入语言中。 (2认同)