2015-05-09 71 views
5

下面的代码工作正常,但我无法弄清楚基于C++标准的哪些点应该是有效的。C++模板指针与成员函数的签名和类型

template< class C, class signature > 
void f(signature C::*ptr) { } 

C = Asignature = void(float, int),函数f将基于该标准的部分,不模板应用于后者是

void f(void(A::*ptr)(float, int)) 

+0

@Daniel弗雷是。我知道所有的作品。我问:为什么这是有效的?我可以在C++标准中读到哪里是适合的。 –

回答

4

最好一一浏览。为了避免歧义,我会在例如

template<class C, class signature> void f(signature C::*ptr) {} 

所有报价指的是C++ 14标准的最新工作草案使用不同的模板参数的名称。

首先我们需要了解模板参数是如何处理的。

[temp.param]/3 A型参数其标识符不遵循省略号限定 其标识符是一个typedef名

所以你的模板定义有两个参数T和签名。当在模板正文使用signature,它因此等同于的typedef

typedef void signature(float, int); 

这typedef的可用于声明一个函数指针参数,如在例如:

[dcl.fct ]/12功能类型的类型定义也可以用来声明功能,但应 不能用来定义一个函数

在TE的参数mplate功能,你写signature T::*ptr,让我们来看看有什么标准说,有关成员指针:

[dcl.mptr]/1在声明T D其中D的形式

nested-name-specifier * attribute-specifier-seq_opt cv-qualifier-seq_opt D1 

嵌套名称说明符表示一个类,并且声明T D1中的 标识符的类型是派生声明器类型列表 T,那么D的标识符的类型是 派生声明器类型列表cv-qualifier-seq指向T类型的类嵌套名称说明符的成员的指针-seq

在我们的例子中,Tsignature,功能的typedef,并DC::*ptr

这解释了编译器将演绎什么类型的例子

void f(void(A::*ptr)(float, int));