代码之家  ›  专栏  ›  技术社区  ›  Vincent

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

  •  1
  • Vincent  · 技术社区  · 6 年前

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

    让我们考虑一种类型 F 至少存在一个组合 Args 因此 std::is_invokable_v<F, Args...> true

    问题【1】: 所有类型是什么 F 可以吗?

    以下是暂定列表:

    • 函数,如 std::function_v<F> 真的
    • 函数指针,使 std::function_v<std::remove_pointer_t<F>> 真的
    • 函数引用,以便 std::function_v<std::remove_reference_t<F>> 真的
    • 对函数指针的引用,使 std::function_v<std::remove_pointer_t<std::remove_reference_t<F>>> 真的
    • 指向成员函数的指针,以便 std::is_member_function_pointer_v<F> 真的
    • 指向成员函数的指针的引用,以便 std::is_member_function_pointer_t<std::remove_reference_t<F>> 真的
    • 指向成员对象的指针,以便 std::is_member_object_pointer_v<F> 真的
    • 指向成员对象的指针的引用,以便 std::is_member_object_pointer_v<std::remove_reference_t<F>> 真的
    • 这样的阶级 std::is_class_v<F> 真的 因此 F::operator() 存在
    • 对类的引用,以使 std::is_class_v<std::remove_reference_t<F>> 真的 因此 std::remove_reference_t<F>::operator() 存在
    • 这样的联盟 std::is_union_v<F> 真的 因此 F: :运算符() 存在
    • 对工会的引用 std::is_union_v<std::remove_reference_t<F>> 真的 因此 std::删除\u reference\u t<F>::运算符() 存在
    • a闭合类型
    • 对闭包类型的引用,以便 std::remove_reference_t<F> 是闭合类型

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

    问题[2]: 闭包类型只是lambda表达式的类型吗?或者在C++中是否有其他方法可以创建闭包类型?

    问题[3]: 该标准有时会讨论函数对象:问题1)列表中的哪些被视为函数对象?

    问题【4】: 执行以下操作:

    • a闭合类型
    • 这样的阶级 标准::is\U class\U v<F> 真的 因此 F: :运算符() 存在
    • 这样的联盟 标准::is\U union\U v<F> 真的 因此 F: :运算符() 存在

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

    2 回复  |  直到 6 年前
        1
  •  3
  •   T.C. Yksisarvinen    6 年前
    1. 表单的函数类型 R(Args...) ,则, R(Args...) noexcept ,则, R(Args......) R(Args......) noexcept
    2. (可能是cv限定的)指向#1的指针。
    3. (可能是cv限定的)至少有一个公共 operator() 成员(包括继承成员);
    4. (可能是cv限定的)至少有一个公共非显式转换函数的类类型,a)引用#1、b)#2或c)引用#2(包括继承的);
    5. (可能是cv限定的)指向成员的指针。
    6. 参考上述内容。

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

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

    A. "callable type" 定义为“函数对象类型或指向成员的指针”,即#2-#5。

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

        2
  •  0
  •   MSalters    6 年前

    我想你错过了

    • 这样的阶级 std::is_class_v<F> true 这样F继承了 operator()

    至于闭包和lambda,请注意C++没有神奇的lambda。lambda只是类类型的对象,通过方便的语法创建。 std::bind 还将产生 Callable 对象,这也可以被视为一个闭包。但是,正如NicolBolas在评论中指出的,“closure”在C++中没有确切的含义,不应该出现在列表中。