On 2/19/2016 3:46 PM, wander wrote:
> Good day!
Yes, and a good day to u2! :)
> I came across an interesting feature in the behavior of popular
> compilers and would like to understand the reasons. There's a simple
> code:
>
> #include <iostream>
>
> template <typename F>
> void (* declval() ) (F);
>
> template <typename X>
> char (& probe( void(*) ( X * ) ) )[1];
>
> template <typename X>
> char (& probe( void(*) ( X ) ) )[2];
>
> int main()
> {
> std::cout << sizeof( probe(declval<void() const>()) );
> }
>
> The question is about type deduction. If you run this code on
> * compiler GCC 4.8.x (or later)
> * compiler Clang 3.4 (or later)
> * compiler in the Visual Stuido (tested on VS 2013 Community)
> * compiler Intel ICC 13.0.1
>
> it will display the number "1".
Huh, that's weird.
The argument type F is not a pointer.
It should not match a pointer, as indicated by result "1".
> And I thought it is logical, since function type, being substituted
> argument in another function, acquires the properties of a pointer
> type.
Oh.
Well, yes, now that you mention it, argument type F should decay to
pointer to function.
Yes.
> On newer versions of compilers mentioned (except for VS and
> ICC) behavior has changed and now this code for Clang 3.5 (or
> higher), GCC 4.9 (or higher) displays the number "2". If you remove
> the second overload, then the mentioned versions of GCC and Clang
> error occurs: "Forming pointer to qualified function type" I
> understand why but doubt whether this rule applies in this context.
Dunno. What's that rule? I could search the standard or just google it,
but I think that the one who asks should provide such info. :)
> Maybe together we can find the truth. Thank you.
Well, whatever this code is meant to support, it can surely be expressed
in some less ambiguous and more clear way?
I'd also change the name `declval` to something not used by the standard
library, or at least put this in a namespace of its own.
In passing, is that `const` really well formed? It's not long ago since
I disabled a sillywarning from MSVC about `const` on function having no
effect, which popped for their own standard library implementation...
Still I feel not quite certain that it's ignored, because when I changed
this to function pointer the compiler complained about it.
Cheers & hth.,
- Alf