具有按签名和类型指向成员函数的指针的 C++ 模板
C++ Templates with pointer to member function by signature and type
下面的代码工作正常,但我无法根据 C++ 标准的哪些点确定它应该有效。
template< class C, class signature >
void f(signature C::*ptr) { }
当C = A
和signature = void(float, int)
时,函数f将是
void f(void(A::*ptr)(float, int))
基于标准的哪些部分,模板是否适用于后者?
最好一一完成。为避免歧义,我将在示例中使用不同的模板参数名称
template<class C, class signature> void f(signature C::*ptr) {}
所有引用均参考 C++14 标准的最新工作草案。
首先我们需要了解,模板参数是如何处理的。
[temp.param]/3 A type-parameter whose identifier does not follow an ellipsis defines
its identifier to be a typedef-name
因此您的模板定义有两个参数 T
和签名。当在模板主体中使用 signature
时,它因此等同于 typedef
typedef void signature(float, int);
此 typedef 可用于声明函数指针参数,如您的示例所示:
[dcl.fct]/12 A typedef of function type may be used to declare a function but shall
not be used to define a function
在模板函数的参数里,你写signature T::*ptr
,我们看看标准对成员指针是怎么说的:
[dcl.mptr]/1 In a declaration T D
where D
has the form
nested-name-specifier * attribute-specifier-seq_opt cv-qualifier-seq_opt D1
and the nested-name-specifier denotes a class, and the type of the
identifier in the declaration T D1
is derived-declarator-type-list
T, then the type of the identifier of D
is
derived-declarator-type-list cv-qualifier-seq pointer to member of class nested-name-specifier of type T.
在我们的例子中,T
是signature
,函数typedef,D
是C::*ptr
。
这解释了编译器将为该示例推断出哪些类型
void f(void(A::*ptr)(float, int));
下面的代码工作正常,但我无法根据 C++ 标准的哪些点确定它应该有效。
template< class C, class signature >
void f(signature C::*ptr) { }
当C = A
和signature = void(float, int)
时,函数f将是
void f(void(A::*ptr)(float, int))
基于标准的哪些部分,模板是否适用于后者?
最好一一完成。为避免歧义,我将在示例中使用不同的模板参数名称
template<class C, class signature> void f(signature C::*ptr) {}
所有引用均参考 C++14 标准的最新工作草案。
首先我们需要了解,模板参数是如何处理的。
[temp.param]/3 A type-parameter whose identifier does not follow an ellipsis defines its identifier to be a typedef-name
因此您的模板定义有两个参数 T
和签名。当在模板主体中使用 signature
时,它因此等同于 typedef
typedef void signature(float, int);
此 typedef 可用于声明函数指针参数,如您的示例所示:
[dcl.fct]/12 A typedef of function type may be used to declare a function but shall not be used to define a function
在模板函数的参数里,你写signature T::*ptr
,我们看看标准对成员指针是怎么说的:
[dcl.mptr]/1 In a declaration
T D
whereD
has the formnested-name-specifier * attribute-specifier-seq_opt cv-qualifier-seq_opt D1
and the nested-name-specifier denotes a class, and the type of the identifier in the declaration
T D1
is derived-declarator-type-list T, then the type of the identifier ofD
is derived-declarator-type-list cv-qualifier-seq pointer to member of class nested-name-specifier of type T.
在我们的例子中,T
是signature
,函数typedef,D
是C::*ptr
。
这解释了编译器将为该示例推断出哪些类型
void f(void(A::*ptr)(float, int));