Question

I was looking at the emulated version of nullptr and saw this converting operator (a member of nullptr_t):

template<class C, class T>    // or any type of null
operator T C::*() const       // member pointer...
{ return 0; }

This syntax for pointer to member function confuses me. I usually expect to see such a type as something like

R (C::*)(I1, I2, ...)

With the template above, there's no input arguments. I can't figure out how the type deduction works in this case. I'm having trouble forming a specific question, other than, how does this work? If I have code like this:

typedef int (MyClass::*MyTypedef)(float);
MyTypedef m = nullptr;

I'm guessing T deduces to int, and C deduces to MyClass. What "happens" to float?

Was it helpful?

Solution

That is a pointer to member, not necessarily a pointer to member function. The difference is that it can generate a pointer to member function or a pointer to non-function member.

Now in the particular use case, the destination is a pointer to member, the compiler is seeing an expression in which it needs a int (MyClass::*)(float), and on the other hand it has a nullptr. It tries to find a conversion and it finds the operator T C::*(), which is a valid conversion if C is deduced to be MyClass and T is deduced to be int (float) [function taking a float and returning an int].

I also find this particular corner of the language a bit confusing (having typedefs, or deduced types for functions), for example this is legal if weird:

typedef void int_f(int);
struct X {
   int_f m;
};
void X::m(int x) { std::cout << x << '\n'; }

The same thing is going on in the conversion operator that you are concerned with.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top