C++ 中哪些类型被认为是可调用的?

What are the types that are considered callables in C++?

我试图理解可以作为 std::invoke 的第一个参数传递的概念和事物类型的层次结构。

让我们考虑一种类型 F,其中存在至少一个 Args 的组合,使得 std::is_invokable_v<F, Args...>true

问题[1]:F可以有哪些类型?

这是一份暂定名单:

这个列表正确吗?还有其他可行的选择吗?

问题 [2]: 闭包类型只是 lambda 表达式的类型,还是在 C++ 中有其他方式创建可以被视为闭包类型的东西?

问题[3]:标准有时会谈到函数对象:问题1)列表中的什么被认为是函数对象?

问题 [4]: 执行以下操作:

属于标准中的特定概念(基本上是具有 operator() 的东西)?如果不是,什么是类型特征的好名字(例如,如果这样的东西在计算机科学或其他编程语言中有一个通用名称),可以检测类型是否满足列出的要点之一?

  1. R(Args...)R(Args...) noexceptR(Args......)R(Args......) noexcept.
  2. 形式的函数类型
  3. (可能 cv-qualified)指向#1。
  4. (可能 cv-qualified) class 类型至少有一个 public operator() 成员(包括继承);
  5. (可能 cv-qualified) class 类型至少有一个 public non-explicit 转换函数到 a) 参考 #1,b) #2,或c) 对#2 的引用(包括继承的);
  6. (可能 cv-qualified)指向成员的指针。
  7. 参考以上内容。

对于#3、#4 及其引用,有一个额外的条件,即类型中编码的 cv-qualification 和值类别必须与至少一个这样的函数兼容。

"Function object types" 是可以使用通常的函数调用语法调用的对象类型,即#2-#4。指向成员的指针不合格,因为您不能用 ().

调用它们

A "callable type" 根据定义是 "a function object types or a pointer to member",即 #2-#5.

函数类型和引用类型不是对象类型,因此既不是函数对象类型也不是可调用类型,但可以通过 std::decay.

的应用成为一个类型

我认为您错过了

中的许多变体
  • a class 这样 std::is_class_v<F> 就是 true 并且 F 继承了一个 operator()

至于闭包和 lambda,请注意 C++ 没有神奇的 lambda。 Lambda 只是 class 类型的对象,通过方便的语法创建。 std::bind 也会产生一个 Callable 对象,这也可以被认为是一个闭包。但是 "closure" 是一个在 C++ 中没有确切含义的标签,不应该出现在列表中,正如 Nicol Bolas 在评论中指出的那样。