15

Usually, a C++ lambda without a capture should be convertable to a c-style function pointer. Somehow, converting it using std::function::target does not work (i.e. returns a nullptr), also the target_type does not match the signature type even though it seems to be the same.

Tested on VC13 and GCC 5.3 / 5.2.0 / 4.8

Minimal testing example:

#include <functional>
#include <iostream>

void Maybe() {

}

void callMe(std::function<void()> callback) {
    typedef void (*ftype)();
    std::cout << (callback.target_type() == typeid(ftype)) << std::endl;
    std::cout << callback.target<ftype>() << std::endl;
}

int main() {
    callMe([] () {});
    callMe(Maybe);
}

expected output would be

1
<address>
1
<address>

actual output

0
0
1
<address>

The question is: Why does the lambda's signature differ from the passed function?

3
  • "... should be convertable to a ..." - citation needed. Commented Jan 13, 2016 at 14:10
  • 4
    @Useless Hmmm, citation is here. Commented Jan 13, 2016 at 14:11
  • @πάνταῥεῖ thanks, i included it in the question Commented Jan 13, 2016 at 14:13

1 Answer 1

18

In your first call, std::function does not bother with decaying the lambda into a pointer, it just stores it, with its actual type (which is indeed not void()).

You can force the lambda to decay into a pointer before constructing the std::function with the latter by simply using a unary +:

callMe(+[](){});
//     ^
Sign up to request clarification or add additional context in comments.

4 Comments

+1, But: I really dislike this + hack for integral/pointer type coercion. It just obscures the intent too much. Better make it explicit by wrapping this into a dedicated function.
So we found a dupe of this Q&A?
@πάνταῥεῖ They are not strictly duplicates (the other ones are about type deduction and overload resolution), but they are indeed quite strongly related.
@KonradRudolph It's a matter of getting used to it, I guess. Hiding it behind, say, a decay(T&&) function wouldn't bother me either.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.