Seriously, I have been thinking at this the whole night and there are two cases
- The language/compiler supports lambdas properly
- Or it does not - like it's the case here
I mean seriously... we are bashing even the expected thing just because we want to be formally correct?Works fine in GCC. Perhaps a compiler bug?
Because in my opinion what GCC is doing is The Right Thing and I don't think they have made it work because of a misconception, an error or a bug. I think it's the right thing to do if we claim to have support for "functional programming" in some language - define a function as you want - you don't change what it is.
My problem here is that I never figured out that the compiler would have cast something in the first place and yes, it was clear to me there were different types going to clash. But heck, we are talking about function pointers!
struct Callbacks {
void (*func)(void); // (2)
Callbacks(void (*func)(void)) : func(call) { }
};
We are not talking about some strange object thing around... that's function pointers at their core but ok, say they are some kind of objects, I would expect, from a properly implemented compiler - it was clear since start VC2010's C++11 was not properly implemented but I didn't expect it so bad - to mandate a relationship like what I draw in the attachment.Yes, those arrows are really meant to be read as "IS-A" relationships.
Note that in this case no casts would be involved and no temporaries would have been generated.
Because if an environment claims to support lambdas... I guess special mangling is happening behind the scenes.
Am I completely unreasonable in thinking no cast should be involved? Maybe a bit but completely... I'm quite sure I'm not. Works fine in GCC. Why? Because I guess GCC authors looked beyond the spec to match the rationale involved: call it some way and define it in code, define it through lambda construct or by an operator(), or by using std::function, they did care about doing the right thing - passing this pointer around. If we would be in 1980 I could understand something is going to break but in post-2000? It was not clear to me.
And it's not a completely crazy thing - I think - , some for loops might emit the same code as some while loops. Intrinsics look like functions but do all sorts of weird data manipulation. Want to talk about OpenMP pragmas?
It's not completely crazy from a purely almost-theorical point of view as well - is this functional or not? Then we care about signature only. It's not that doing typedef char sbyte changes what happens at the basic level and that's the same behavior I would expect from a compiler - functions don't change what they are at their core... define them as you want. Because I don't see how lambdas should change what a function is - and I'm not even considering capture lists.
So I guess at this point my hate goes to Microsoft, because even taking in consideration what you have written - which I consider valuable and reasonable but sort of missing the point - I still think they could have considered making an explicit ctor call from lambdas, or emit a warning or whatever, since they clearly had to ship a rushed implementation (not even casting correctly to function pointer), I guess they could have gone at least so far, I guess the sentiment is shared.
As a side note I still don't quite understand why references cannot be copied. It's not like an automatically dereferenced pointer is some kind of funky entity. Why they couldn't be assigned I could understand but copy... but that's not the point anyway, I am aware of this problem.Storing objects by reference this way is "risky" precisely because of implicit conversions. Also because one cannot properly implement assignment operator, meaning objects storing references are non-copyable.
I want to thank you all for your patience.