Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   SFINAE -- basis: array of void is invalid type (http://www.velocityreviews.com/forums/t617398-sfinae-basis-array-of-void-is-invalid-type.html)

Barry 05-29-2008 06:36 AM

SFINAE -- basis: array of void is invalid type
 
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<void> should 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
<void> at line 18

compiles with gcc 4.3.0 but produced unexpected result, producing
T
T
which means that f<int>, f<void> both 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 05-29-2008 08:55 AM

Re: SFINAE -- basis: array of void is invalid type
 
On 29 mai, 08:36, Barry <dhb2...@gmail.com> wrote:
> 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<void> should 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
> * * * * * * * * * * *<void> at line 18
>
> compiles with gcc 4.3.0 but produced unexpected result, producing
> T
> T
> which means that f<int>, f<void> both 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"

> 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 05-29-2008 03:43 PM

Re: SFINAE -- basis: array of void is invalid type
 
courpron@gmail.com wrote:
> On 29 mai, 08:36, Barry <dhb2...@gmail.com> wrote:
>> 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<void> should 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
>> <void> at line 18
>>
>> compiles with gcc 4.3.0 but produced unexpected result, producing
>> T
>> T
>> which means that f<int>, f<void> both 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"
>
>> 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


All times are GMT. The time now is 03:17 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.