convert lambda to member function pointer

1,364 views
Skip to first unread message

Nick

unread,
Feb 18, 2014, 12:08:05 AM2/18/14
to std-pr...@isocpp.org
If a lambda expression with an empty capture list can be converted to a regular function pointer, could a lambda expression which only captures [this] be converted to a member function pointer for the enclosing class, such that the following code would be legal?

struct foo {
   
int i;

   
void bar() {
       
void(foo::*pfn)() = [this](){ cout << i << endl; };
   
}
};


David Krauss

unread,
Feb 18, 2014, 12:14:04 AM2/18/14
to std-pr...@isocpp.org
On Feb 18, 2014, at 1:08 PM, Nick <nicolas.j...@gmail.com> wrote:

If a lambda expression with an empty capture list can be converted to a regular function pointer, could a lambda expression which only captures [this] be converted to a member function pointer for the enclosing class, such that the following code would be legal?

No; a PTMF does not store the value of this, which you need.

Since the binding of this is intrinsic to the construction of a lambda, you can’t factor out the storage of this to get a PTMF interface plus a separate object pointer, either.

Brent Friedman

unread,
Feb 18, 2014, 12:28:26 AM2/18/14
to std-pr...@isocpp.org
That won't do you any good. Member function pointers don't remember the object that they are to be called on. You are capturing the exact object instance that you want the function called on (this), but member function pointers do no such thing. In your example, you might do (this->*pfn)() or (that->*pfn)().

I think what you would want is [](foo* f){...} to be convertible to a member function pointer.

And if you can do that, then you should also be able to convert free functions to a member function pointer as well. void (foo*) to void(foo::*)()

And convert void (foo*, int) into a void(foo::*)(int)


--
 
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

Billy O'Neal

unread,
Feb 18, 2014, 12:31:29 AM2/18/14
to std-proposals
Can't you already do that with mem_fn or bind?

David Krauss

unread,
Feb 18, 2014, 12:48:06 AM2/18/14
to std-pr...@isocpp.org
On Feb 18, 2014, at 1:31 PM, Billy O'Neal <billy...@gmail.com> wrote:

Can't you already do that with mem_fn or bind?

They go the other way, from PTMF to non-PTMF. But PTMFs are allowed to accept the this argument with different ABI than other functions, and have a special lazy virtual binding semantic, so you can’t really just hack regular functions to fit.

In general you should only use a PTMF if you’re sure that’s what you want in the first place. Solution to OP here is probably that he should scrub them from his interfaces in favor of unary std::function.

billy...@gmail.com

unread,
Feb 18, 2014, 1:01:19 AM2/18/14
to std-proposals
Oh, derp :)

Sent from a touchscreen. Please excuse the brevity and tpyos.

Nick

unread,
Feb 18, 2014, 10:30:26 AM2/18/14
to std-pr...@isocpp.org
Thanks for the responses. After a second look, I seem to have been mistaken in thinking that the following code was a special case:

void(*fn)() = [](){ cout << "hello world" << endl; };

I thought that the construction of the lambda/function object would have been elided in this case, but after reviewing the disassembly, it seems that the above is done by calling a conversion operator.

Under the above premise, I assumed that only capturing [this] would ensure that the code inside the lambda would also be legal as a member function, and could be special cased.

I didn't intend for [this] to actually be captured, but only for it to tell the compiler that the code inside the lambda should be legal as a member function.

Billy O'Neal

unread,
Feb 18, 2014, 10:53:31 AM2/18/14
to std-proposals
void(*fn) {} is not a pointer to member declaration, so you wouldn't want the compiler to make it a member function anyway.

Nick

unread,
Feb 18, 2014, 12:50:26 PM2/18/14
to std-pr...@isocpp.org
That's not what I meant. Basically, what I am suggesting would be implemented by adding a conversion operator returning a ptmf when the capture list contains only [this].

typedef (T::*ptmf_t)() ;
lambda::operator ptmf_t();

Nevin Liber

unread,
Feb 18, 2014, 12:55:17 PM2/18/14
to std-pr...@isocpp.org
On 18 February 2014 11:50, Nick <nicolas.j...@gmail.com> wrote:
That's not what I meant. Basically, what I am suggesting would be implemented by adding a conversion operator returning a ptmf when the capture list contains only [this].

So you want it to convert to something that doesn't actually have a captured this?
--
 Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com(847) 691-1404

Nick

unread,
Feb 18, 2014, 1:01:33 PM2/18/14
to std-pr...@isocpp.org
Yes.

Sean Middleditch

unread,
Feb 18, 2014, 2:35:21 PM2/18/14
to std-pr...@isocpp.org
On Tuesday, February 18, 2014 10:01:33 AM UTC-8, Nick wrote:
Yes.

That would be semantically really confusing and weird.

If you really need support for such a feature, a more logical syntax would not involve a bogus capture but would either explicitly indicate that the lambda requires 'this' be provided by the caller, e.g. [](Foo* this){ /* stuff */ }, or would allow any function with a pointer-to-class as the first parameter be convertible to member function pointer for that class type with the signature modified to remove that parameter, e.g. [](Foo* pFoo, int a, char b)->float{} converts to float(Foo::*)(int,char) and [](const Foo*){} converts to void(Foo::*)()const.

I'm unconvinced you at all need this instead of just using std::function, though.  Conversion to regular function pointer makes sense for C compatibility which will never grow support for C++ types, but C++ code can just use the new stdlib types.  Even most legacy C++ code could be converted more easily than requiring use of this feature given that it'll be years before any new feature potentially coming out of this discussion would ever be in a shipping compiler.
Reply all
Reply to author
Forward
0 new messages