cv-qualified function type and type deduction

Skip to first unread message


Feb 20, 2016, 8:20:16 AM2/20/16

Good day!
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". And I thought it is logical, since
function type, being substituted argument in another function, acquires
the properties of a pointer type.
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.

In particular, it would be interesting to know whether the behavior of
the new and old versions of the compilers conforms to C++ Standard.

Maybe together we can find the truth.
Thank you.

[ See for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Daniel Krügler

Feb 22, 2016, 8:50:15 PM2/22/16
My interpretation of the code is that it should be required to be
ill-formed after acceptance of

because it is not valid to form a pointer to a function with
cv-qualifier-seq (In the example: 'void() const'). It is somewhat
interesting to note that this interpretation also depends on the
semantics of function parameter decay which is also discussed by

But even if the details of CWG 1668 are not clarified yet, I believe it
is save to assume that the transformation mentioned in [dcl.fct] p5

"After determining the type of each parameter, any parameter of type
“array of T” or of function type T is adjusted to be “pointer to T”.

would produce an invalid type and would require a diagnostics, because
the function type is 'void() const'. The wording details of CWG 1668
will hopefully clarify further details, e.g. whether the substituation
attempt for dependent function parameters will effectively lead to
SFINAE, but regardless of that detail, the presented example doesn't
provide any third valid fall-back for 'probe' that could be selected, so

there should be no function probe that could be selected by overload

HTH & Greetings from Bremen,

Daniel Krügler
Reply all
Reply to author
0 new messages