The code below works fine but I can't figure out based what points of the C++ standard it should be valid.
template< class C, class signature >
void f(signature C::*ptr) { }
When C = A
and signature = void(float, int)
, the function f will be
void f(void(A::*ptr)(float, int))
Based on which parts of the standard, does the template apply to the latter?
Best go through this one by one. To avoid ambiguities, I'll use different template argument names in the example
template<class C, class signature> void f(signature C::*ptr) {}
All quotes refer to the latest working draft of the C++14 standard.
First we need to understand, how the template parameters are treated.
[temp.param]/3 A type-parameter whose identifier does not follow an ellipsis defines its identifier to be a typedef-name
So your template definition has two parameters T
and the signature. When using signature
in the template body, it is therefore equivalent to the typedef
typedef void signature(float, int);
This typedef may be used to declare a function pointer parameter, as in your example:
[dcl.fct]/12 A typedef of function type may be used to declare a function but shall not be used to define a function
In the parameters of the template function, you write signature T::*ptr
, let's see what the standard says about member pointers:
[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.
In our example, T
is signature
, the function typedef, and D
is C::*ptr
.
This explains what types the compiler will deduce for the example
void f(void(A::*ptr)(float, int));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With