Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is wrong with this pointer to member conversion?

Tags:

c++

c++11

What is wrong with this code? I thought I could convert due to this answer:

Is it safe to "upcast" a method pointer and use it with base class pointer?

struct B
{
  void f(){}
};

struct D : B
{
  virtual ~D(){}
};

template <typename FP, FP fp>
void g()
{
}

int main()
{
  g<void (D::*)(), &B::f>();
  return 0;
}

Error:

t.cpp:18:27: error: could not convert template argument '&B::f' to 'void (D::*)()'
   g<void (D::*)(), &B::f>();

This doesn't work either:

g<void (D::*)(), static_cast<void (D::*)()>(&B::f)>();
like image 465
user1095108 Avatar asked Sep 14 '26 13:09

user1095108


1 Answers

This is disallowed by the standard (C++11, [temp.arg.nontype]§5):

The following conversions are performed on each expression used as a non-type template-argument. If a non-type template-argument cannot be converted to the type of the corresponding template-parameter then the program is ill-formed.

...

  • 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).

(Emphasis mine)

Casts are not allowed either, because of [temp.arg.nontype]§1:

A template-argument for a non-type, non-template template-parameter shall be one of:

...

  • a pointer to member expressed as described in 5.3.1.

Where 5.3.1§4 reads:

A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses.

This combines to say that a cast experssion is not allowed as a non-type template argument.

So, while such conversions are possible at runtime, it seems there's no way to use them as template arguments.

like image 194
Angew is no longer proud of SO Avatar answered Sep 16 '26 03:09

Angew is no longer proud of SO