Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > SFINAE -- basis: array of void is invalid type

Reply
Thread Tools

SFINAE -- basis: array of void is invalid type

 
 
Barry
Guest
Posts: n/a
 
      05-29-2008
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
 
Reply With Quote
 
 
 
 
courpron@gmail.com
Guest
Posts: n/a
 
      05-29-2008
On 29 mai, 08:36, Barry <(E-Mail Removed)> 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.
 
Reply With Quote
 
 
 
 
Fei Liu
Guest
Posts: n/a
 
      05-29-2008
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> On 29 mai, 08:36, Barry <(E-Mail Removed)> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What is the difference between void proba(); and void proba(void); ??? PencoOdStip@gmail.com C++ 1 05-23-2007 07:12 PM
invalid conversion from `const void*' to `void*' philwozza C++ 3 05-13-2006 12:59 AM
what is the difference, void func(void) and void fucn() noblesantosh@yahoo.com C Programming 5 07-22-2005 04:38 PM
"void Method()" vs "void Method(void)" Ollej Reemt C++ 7 04-22-2005 03:47 AM
`void **' revisited: void *pop(void **root) Stig Brautaset C Programming 15 10-28-2003 09:03 AM



Advertisments