Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a superclass function as non typename template parameter

Tags:

c++

templates

Suppose you have

  struct A{
  void f(){}
};


struct B:public A{
};


template<typename C,void (C::*f)()>
struct Call{

  void operator()(C* c){
    (c->*f)();
  }
};

why does

int main(){
  void (B::*f)()=&B::f;    
}

work but

 Call<B,&B::f> a;

doesn't, complaining

could not convert template argument ‘&A::f’ to ‘void (B::*)()

?

(Call<A,&A::f> clearly works)

In a similar way

const void (B::*f)()=&B::f;

gives

cannot convert ‘void (A::*)()’ to ‘const void (B::*)()’ in initialization
like image 827
Fabio Dalla Libera Avatar asked Jun 21 '12 12:06

Fabio Dalla Libera


Video Answer


1 Answers

void (B::*f)()=&B::f;   

works because implicit conversion from

void (A::*f)() 

to

void (B::*f)()

is applied.

4.11 (2)

A prvalue of type “pointer to member of B of type cv T”, where B is a class type, can be converted to a prvalue of type “pointer to member of D of type cv T”, where D is a derived class (Clause 10) of B.

However, the standard doesn't allow any conversions for pointer to member function in template arguments except of nullptr_t conversion:

14.3.2

For a non-type template-parameter of type pointer to member function, if the template-argument is of type std::nullptr_t, the null member pointer conversion (4.11) is applied; otherwise, no conversions apply. If the template-argument represents a set of overloaded member functions, the matching member function is selected from the set (13.4).

like image 59
user396672 Avatar answered Oct 04 '22 03:10

user396672