理解函数指针和引用

Understanding function pointers and reference

考虑以下类型:

template <class R, class... Args> using type0 = R(Args...);
template <class R, class... Args> using type1 = R(*)(Args...);
template <class R, class... Args> using type2 = R(&)(Args...);
template <class R, class C, class... Args> using type3 = R(C::*)(Args...);
template <class R, class C, class... Args> using type4 = R(C::&)(Args...);
// Any other existing syntax? R(&&)(Args...)? R(const*)(Args...)? R()(Args..)?

实际存在哪些类型? type0type1type2type3type4有什么区别?中间的括号是什么意思?它们都是函数指针吗?我在哪里可以找到关于此语法的详尽文档,因为我不太清楚?

通过别名模板 type0type3 实例化的类型都存在。但是,您不能拥有函数类型的对象,即,没有通过别名模板 type0.

实例化的类型的实例

没有 "reference to member" 类型,也就是说,我认为 type4 行不通

这些类型相当容易理解:

  1. R(Args...) 是函数 value 类型(return R 并以 Args... 作为参数)。本质上,这就是函数的类型。 C++ 不允许这种类型的值。
  2. R(*)(Args...)是函数指针类型。 * 周围的圆括号(如果有名称,则为 (*name) 中的名称)用于消除 * 是否绑定到 return 类型 [=21] 的歧义=](默认值)或函数类型(有括号时)。当你想在某处传递一个函数时,你不使用函数值而是使用函数指针。您可以通过函数指针调用函数。您可以将函数指针视为函数实现所在的地址,尽管不能保证这也是它的实现方式。
  3. R(&)(Args...) 是函数 reference 类型。函数指针和函数引用之间的关系与指针和引用之间的关系相同:如果您取消引用函数指针,您将获得一个函数引用。
  4. R(C::*)(Args...)是成员函数指针类型。这本质上是成员函数的句柄。这些更像是成员函数列表的索引,但标识了一个成员函数。使用对象 o 和成员函数指针 mem,您可以使用类似 (o.*mem)(args...) 的方式调用成员函数。如果用于初始化指向成员的指针的成员函数是 virtual 将会发生动态调度(我认为在通过成员函数指针调用时没有办法阻止动态调度)。

除了列出的那些函数声明之外,成员函数指针类型可以具有 const/volatile and/or 引用限定,并且函数类型有可变参数版本。即还有

  • 指向 const 成员的指针:

    template <class R, class C, class... Args>
    using mem_const = R(C::*)(Args...) const`
    
  • 指向 volatile 成员的指针:

    template <class R, class C, class... Args>
    using mem_volatile =  R(C::*)(Args...) volatile
    
  • 指向 const volatile 成员的指针:

    template <class R, class C, class... Args>
    using mem_const_volatile =  R(C::*)(Args...) const volatile
    
  • 指向左值合格成员的指针:

    template <class R, class C, class... Args>
    using mem_lvalue =  R(C::*)(Args...) &;
    
  • 指向右值合格成员的指针:

    template <class R, class C, class... Args>
    using mem_rvalue =  R(C::*)(Args...) &&;
    
  • const/volatile和lvalue/rvalue资格的所有组合。

  • 函数类型的可变参数列表版本(...... 也可以写成 ... ......, ...):

    template <class R, class... Args>
    using varargs = R(Args......);
    
  • 具有尾随变量参数列表的所有函数指针、引用和成员函数指针类型。

我认为这是 [当前] 一个相当详尽的函数和成员函数列表,它们的合格版本和它们的 pointer/reference 版本。随着 C++17 也将异常规范添加到组合中,还将有一个 noexcept(true) 版本(除了默认的 noexcept(false) 版本。