Connecting Tech Pros Worldwide Forums | Help | Site Map

SFINAE -- basis: array of void is invalid type

Barry
Guest
 
Posts: n/a
#1: Jun 27 '08
The problem brought by one earlier post from comp.lang.c++
http://groups.google.com/group/comp....636c48b84957b/

I take part of the question and reproduce the code to represent (partly)
the question.

#include <iostream>

template <class>
void f(...)
{
std::cout << "..." << std::endl;
}

template <class T>
void f(T[1])
{
std::cout << "T" << std::endl;
}

int main()
{
f<int>(0);
f<void>(0);
}


as "array of void" is invalid type, so the f<voidshould applies SFINAE
and chooses the "f(...)" version

the code above compiles and runs _expectedly_ with VC8
but fails to compile with Comuea Online, producing the error message:

"ComeauTest.c", line 10: error: array of void is not allowed
void f(T[1])
^
detected during instantiation of "f" based on template argument
<voidat line 18

compiles with gcc 4.3.0 but produced unexpected result, producing
T
T
which means that f<int>, f<voidboth chooses the second version.

so who's right about this?

one more question:
should

8.3.5.3 [...] The type of a function is determined using the
following rules. The type of each parameter is determined from its own
decl-specifier-seq and declarator. After determining the type of each
parameter, any parameter of type “array of T” or “function returning
T” is adjusted to be “pointer to T” or “pointer to function returning
T,” respectively.
[...]

the adjustment apply before SFINAE happens?
I guess GCC4.3.0 gives an "yes" answer.


--
Best Regards
Barry

courpron@gmail.com
Guest
 
Posts: n/a
#2: Jun 27 '08

re: SFINAE -- basis: array of void is invalid type


On 29 mai, 08:36, Barry <dhb2...@gmail.comwrote:
Quote:
The problem brought by one earlier post from comp.lang.c++http://groups.google.com/group/comp....ead/thread/bf6...
>
I take part of the question and reproduce the code to represent (partly)
the question.
>
#include <iostream>
>
template <class>
void f(...)
{
* *std::cout << "..." << std::endl;
>
}
>
template <class T>
void f(T[1])
{
* *std::cout << "T" << std::endl;
>
}
>
int main()
{
* *f<int>(0);
* *f<void>(0);
>
}
>
as "array of void" is invalid type, so the f<voidshould applies SFINAE
and chooses the "f(...)" version
>
the code above compiles and runs _expectedly_ with VC8
but fails to compile with Comuea Online, producing the error message:
>
"ComeauTest.c", line 10: error: array of void is not allowed
* *void f(T[1])
* * * * * *^
* * * * * *detected during instantiation of "f" based on template argument
* * * * * * * * * * *<voidat line 18
>
compiles with gcc 4.3.0 but produced unexpected result, producing
T
T
which means that f<int>, f<voidboth chooses the second version.
>
so who's right about this?
I guess VC8 is right.

SFINAE comes when type deduction fails, which can happen in the
following context :

14.8.2.2 :

"When an explicit template argument list is specified, the template
arguments must be compatible with the template parameter list and must
result in a valid function type as described below; otherwise type
deduction fails. Specifically, [...] Type deduction may fail for the
following reasons:
Attempting to create an array with an element type that is void"
Quote:
one more question:
should
>
8.3.5.3 [...] The type of a function is determined using the
following rules. The type of each parameter is determined from its own
decl-specifier-seq and declarator. After determining the type of each
parameter, any parameter of type array of T or function returning
T is adjusted to be pointer to T or pointer to function returning
T, respectively.
[...]
>
the adjustment apply before SFINAE happens?
I guess GCC4.3.0 gives an "yes" answer.

Such adjustement is applied after SFINAE.

14.8.2.3 :

"After this substitution is performed, the function parameter type
adjustments described in 8.3.5 are performed."

Alexandre Courpron.
Fei Liu
Guest
 
Posts: n/a
#3: Jun 27 '08

re: SFINAE -- basis: array of void is invalid type


courpron@gmail.com wrote:
Quote:
On 29 mai, 08:36, Barry <dhb2...@gmail.comwrote:
Quote:
>The problem brought by one earlier post from comp.lang.c++http://groups.google.com/group/comp....ead/thread/bf6...
>>
>I take part of the question and reproduce the code to represent (partly)
>the question.
>>
>#include <iostream>
>>
>template <class>
>void f(...)
>{
> std::cout << "..." << std::endl;
>>
>}
>>
>template <class T>
>void f(T[1])
>{
> std::cout << "T" << std::endl;
>>
>}
>>
>int main()
>{
> f<int>(0);
> f<void>(0);
>>
>}
>>
>as "array of void" is invalid type, so the f<voidshould applies SFINAE
>and chooses the "f(...)" version
>>
>the code above compiles and runs _expectedly_ with VC8
>but fails to compile with Comuea Online, producing the error message:
>>
>"ComeauTest.c", line 10: error: array of void is not allowed
> void f(T[1])
> ^
> detected during instantiation of "f" based on template argument
> <voidat line 18
>>
>compiles with gcc 4.3.0 but produced unexpected result, producing
>T
>T
>which means that f<int>, f<voidboth chooses the second version.
>>
>so who's right about this?
>
I guess VC8 is right.
>
SFINAE comes when type deduction fails, which can happen in the
following context :
>
14.8.2.2 :
>
"When an explicit template argument list is specified, the template
arguments must be compatible with the template parameter list and must
result in a valid function type as described below; otherwise type
deduction fails. Specifically, [...] Type deduction may fail for the
following reasons:
Attempting to create an array with an element type that is void"
>
Quote:
>one more question:
>should
>>
>8.3.5.3 [...] The type of a function is determined using the
>following rules. The type of each parameter is determined from its own
>decl-specifier-seq and declarator. After determining the type of each
>parameter, any parameter of type array of T or function returning
>T is adjusted to be pointer to T or pointer to function returning
>T, respectively.
>[...]
>>
>the adjustment apply before SFINAE happens?
>I guess GCC4.3.0 gives an "yes" answer.
>
>
Such adjustement is applied after SFINAE.
>
14.8.2.3 :
>
"After this substitution is performed, the function parameter type
adjustments described in 8.3.5 are performed."
>
Alexandre Courpron.
This suggests that VC8 is probably doing the correct thing. First SFINAE
kicks in and the ... version is chosen, then void[1] decays to void *
and becomes a valid type.

Although now I could understand why comeau is reporting an error, not
taking into account the decay effect, void[1] is an invalid type
regardless. But in the same vein, it's still doing something wrong when
it takes void(*)[1] without reporting any error.

SFINAE needs to be better standardized and documented. Intel compiler
behaves exactly like comeau, different from g++ and vc8.

Fei
Closed Thread


Similar C / C++ bytes