考虑以下类型:
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..)?
实际存在哪些类型? type0
,type1
,type2
,type3
,type4
之间有什么区别?中间括号是什么意思?它们都是函数指针吗?我在哪里可以找到关于这种语法的详尽文档,因为我不清楚它?
答案 0 :(得分:4)
通过别名模板type0
到type3
实例化的类型都存在。但是,您不能拥有函数类型的对象,即,没有通过别名模板type0
实例化类型的实例。
没有“成员参考”类型,即我认为type4
不起作用
这些类型相当容易理解:
R(Args...)
是一个函数 value 类型(返回R
并将Args...
作为参数)。从本质上讲,这是函数的类型。 C ++不允许使用此类型的值。R(*)(Args...)
是一个函数指针类型。 *
周围的括号(如果有名称,名称为(*name)
)需要消除歧义*
是否绑定到返回类型R
(默认)或函数类型(有括号时)。如果要在某处传递函数,则不使用函数值而是使用函数指针。您可以通过函数指针调用函数。您可以将函数指针视为函数实现所在的地址,尽管不能保证这也是它的实现方式。R(&)(Args...)
是一个函数引用类型。函数指针和函数引用之间的关系与指针和引用之间的关系相同:如果取消引用函数指针,你将获得一个函数引用。R(C::*)(Args...)
是成员函数指针类型。这实际上是成员函数的句柄。这些更像是成员函数列表中的索引,但标识成员函数。使用对象o
和成员函数指针mem
,您可以使用(o.*mem)(args...)
之类的内容调用成员函数。如果用于初始化成员指针的成员函数是virtual
,则会发生动态调度(我不认为在通过成员函数指针调用时有一种阻止动态调度的方法)。除了列出的那些函数声明之外,成员函数指针类型还可以有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)
版本。