理解函数指针和引用

时间:2015-12-01 19:43:54

标签: c++ function c++11 function-pointers pointer-to-member

考虑以下类型:

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之间有什么区别?中间括号是什么意思?它们都是函数指针吗?我在哪里可以找到关于这种语法的详尽文档,因为我不清楚它?

1 个答案:

答案 0 :(得分:4)

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

没有“成员参考”类型,即我认为type4不起作用

这些类型相当容易理解:

  1. R(Args...)是一个函数 value 类型(返回R并将Args...作为参数)。从本质上讲,这是函数的类型。 C ++不允许使用此类型的值。
  2. R(*)(Args...)是一个函数指针类型。 *周围的括号(如果有名称,名称为(*name))需要消除歧义*是否绑定到返回类型R(默认)或函数类型(有括号时)。如果要在某处传递函数,则不使用函数值而是使用函数指针。您可以通过函数指针调用函数。您可以将函数指针视为函数实现所在的地址,尽管不能保证这也是它的实现方式。
  3. R(&)(Args...)是一个函数引用类型。函数指针和函数引用之间的关系与指针和引用之间的关系相同:如果取消引用函数指针,你将获得一个函数引用。
  4. R(C::*)(Args...)是成员函数指针类型。这实际上是成员函数的句柄。这些更像是成员函数列表中的索引,但标识成员函数。使用对象o和成员函数指针mem,您可以使用(o.*mem)(args...)之类的内容调用成员函数。如果用于初始化成员指针的成员函数是virtual,则会发生动态调度(我不认为在通过成员函数指针调用时有一种阻止动态调度的方法)。
  5. 除了列出的那些函数声明之外,成员函数指针类型还可以有const / volatile和/或ref-qualification,并且函数类型有可变参数版本。也就是说,还有

    • 指向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...) &;
      
    • 指向rvalue合格成员的指针:

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

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

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

    我认为这[目前]是一个相当详尽的函数和成员函数列表,它们的限定版本以及它们的指针/引用版本。使用C ++ 17还可以在混合中添加异常规范,还会有noexcept(true)版本(除了默认的noexcept(false)版本。