 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Alexander Stippler Guest
|
Posted: Wed Oct 29, 2003 9:34 am Post subject: overload resolution / integral promotion / standard |
|
|
Hi,
I have got a question concerning the overload resolution rules of C++ and
enumeration types. The following little test program illustrates the
situation:
enum { red, green, blue };
template <class A, class B>
A
operator+(const A &a, const B& b)
{
return a;
}
int
main()
{
int i = 0;
i = i + green;
return 0;
}
The code does not really make much sense, but illustrates my problem: I
would never have guessed that every compiler I tried uses the template
operator+ instead of a builtin +.
IMO the compiler has to prefer the builtin + according to the standard:
1) both the user-defined + and the builtin + are in the candidate set.
[13.3.1/13.3.2] and [13.6.2/13.6.12].
2) both are viable.
3) but the built-in + is better [13.3.3].
By the way, I have neglected the fact, that the enum is an unnamed type, so
that the compiler should not choose the template version anyway (or should
it?)
Are my considerations wrong or the compilers (gcc3.3, como4.3, icc7.01)?
regards,
alex
|
|
| Back to top |
|
 |
Rob Williscroft Guest
|
Posted: Wed Oct 29, 2003 12:23 pm Post subject: Re: overload resolution / integral promotion / standard |
|
|
Alexander Stippler wrote in news:3f9f89c1 (AT) news (DOT) uni-ulm.de:
| Quote: | Hi,
I have got a question concerning the overload resolution rules of C++
and enumeration types. The following little test program illustrates
the situation:
enum { red, green, blue };
template <class A, class B
A
operator+(const A &a, const B& b)
{
return a;
}
int
main()
{
int i = 0;
i = i + green;
return 0;
}
The code does not really make much sense, but illustrates my problem:
I would never have guessed that every compiler I tried uses the
template
operator+ instead of a builtin +.
IMO the compiler has to prefer the builtin + according to the
standard:
1) both the user-defined + and the builtin + are in the candidate set.
[13.3.1/13.3.2] and [13.6.2/13.6.12].
2) both are viable.
3) but the built-in + is better [13.3.3].
|
Well the builtin requires an extra conversion enum to int. Note that
argument conversion sequences are considered before other rules,
for instance the "prefere non-template over template" rule.
| Quote: |
By the way, I have neglected the fact, that the enum is an unnamed
type, so that the compiler should not choose the template version
anyway (or should it?)
|
I've read this argument before, though I've never read of a compiler
that actually doesn't treat unnamed enum's as though they have a
type-name.
Ok just found one:
enum { red, green, blue };
template
A operator+(const A &a, const B& b)
{
return a;
}
struct Dumby {};
Dumby operator + ( Dumby const &, int );
int main()
{
Dumby i;
i = i + green;
return 0;
}
"sourceFile.cpp", line 17: error:
a template argument may not reference an unnamed type
i = i + green;
^
The compiler is at http://www.dinkumware.com/exam/dinkumExam.aspx
It gives:
"sourceFile.cpp", line 13: error:
identifier "green" is undefined
i = i + green;
^
for your original code.
I don't know what EDG version this is. So I've now idea if its more
recient than the como compiler you tried.
Clearly the compiler doesn't consider SFINAE to apply, I would
hazard a guess that this is an illegal substitution not a
"Substitution Failure", hence it doesn't select the builtin op +
anyway.
Rob.
--
http://www.victim-prime.dsl.pipex.com/
|
|
| Back to top |
|
 |
Rob Williscroft Guest
|
Posted: Wed Oct 29, 2003 12:26 pm Post subject: Re: overload resolution / integral promotion / standard |
|
|
Rolf Magnus wrote in news:bno9fc$sf5$07$1 (AT) news (DOT) t-online.com:
| Quote: | By the way, I have neglected the fact, that the enum is an unnamed
type, so that the compiler should not choose the template version
anyway (or should it?)
Why should there be any difference between a named and an unnamed enum
type?
|
IIUC because it needs a name with external linkage to base the
external-linkage name it's going to give to the instantiated
operator + < A, ( A const &, <unnamed-type> const &).
Rob.
--
http://www.victim-prime.dsl.pipex.com/
|
|
| Back to top |
|
 |
Alexander Stippler Guest
|
Posted: Wed Oct 29, 2003 12:58 pm Post subject: Re: overload resolution / integral promotion / standard |
|
|
Rob Williscroft wrote:
| Quote: |
enum { red, green, blue };
template
A
operator+(const A &a, const B& b)
{
return a;
}
int
main()
{
int i = 0;
i = i + green;
return 0;
}
Well the builtin requires an extra conversion enum to int. Note that
argument conversion sequences are considered before other rules,
for instance the "prefere non-template over template" rule.
|
Your completely right here.
Well,
the standard says: "If a substitution in a template parameter or in the
function type of the function template results in an invalid type, type
deduction fails." A unnamed type is and invalid type, so what?
como emits the error message:
"a template argument may not reference an unnamed type"
So it notices that it is an unnamed type, but it doesn't treat it as invalid
type in template argument deduction. Would it not have to?
intel C++ and gcc choose the template version anyway.
regards,
alex
|
|
| Back to top |
|
 |
tom_usenet Guest
|
Posted: Wed Oct 29, 2003 2:47 pm Post subject: Re: overload resolution / integral promotion / standard |
|
|
On Wed, 29 Oct 2003 13:58:37 +0100, Alexander Stippler
<stip (AT) mathematik (DOT) uni-ulm.de> wrote:
| Quote: | Well,
the standard says: "If a substitution in a template parameter or in the
function type of the function template results in an invalid type, type
deduction fails." A unnamed type is and invalid type, so what?
como emits the error message:
"a template argument may not reference an unnamed type"
So it notices that it is an unnamed type, but it doesn't treat it as invalid
type in template argument deduction. Would it not have to?
intel C++ and gcc choose the template version anyway.
|
The list of substitutions that cause type deduction to fail are listed
in 14.8.2/2. This one isn't mentioned (using a non-extern type), so
14.8.2/5 applies and I assume it should give an error (as EDG does).
Tom
|
|
| Back to top |
|
 |
Alexander Stippler Guest
|
Posted: Wed Oct 29, 2003 3:10 pm Post subject: Re: overload resolution / integral promotion / standard |
|
|
tom_usenet wrote:
| Quote: | On Wed, 29 Oct 2003 13:58:37 +0100, Alexander Stippler
[email]stip (AT) mathematik (DOT) uni-ulm.de[/email]> wrote:
Well,
the standard says: "If a substitution in a template parameter or in the
function type of the function template results in an invalid type, type
deduction fails." A unnamed type is and invalid type, so what?
como emits the error message:
"a template argument may not reference an unnamed type"
So it notices that it is an unnamed type, but it doesn't treat it as
invalid type in template argument deduction. Would it not have to?
intel C++ and gcc choose the template version anyway.
The list of substitutions that cause type deduction to fail are listed
in 14.8.2/2. This one isn't mentioned (using a non-extern type), so
14.8.2/5 applies and I assume it should give an error (as EDG does).
Tom
|
I think the standard is not very precise here. IMO a compiler should not
consider a template function in the given context, since it would have to
instantiate it with an unnamed type, what is not allowed. And the standard
says:
"Template arguments can be deduced in several different contexts, but in
each case a type that is specified in terms of template parameters(call it
P) is compared with an actual type (call it A). and an attempt is made to
find template argument values ( ... ) that will make P, after substitution
of the deduced values (call it the deduced A), compatible with A.
[14.8.2.4] IMO a compiler should therefore not try any unnamed type as
template parameter anyway in this process, since this does not make sense -
they are not allowed. So why try them?
To me - independent of what the standard says - it would make sense to
handle it the way I proposed. What do you think?
regards,
alex
|
|
| Back to top |
|
 |
Rob Williscroft Guest
|
Posted: Wed Oct 29, 2003 3:22 pm Post subject: Re: overload resolution / integral promotion / standard |
|
|
Alexander Stippler wrote in news:3f9fb9a5 (AT) news (DOT) uni-ulm.de:
| Quote: | Your completely right here.
Well,
the standard says: "If a substitution in a template parameter or in
the function type of the function template results in an invalid type,
type deduction fails." A unnamed type is and invalid type, so what?
como emits the error message:
"a template argument may not reference an unnamed type"
So it notices that it is an unnamed type, but it doesn't treat it as
invalid type in template argument deduction. Would it not have to?
intel C++ and gcc choose the template version anyway.
|
In the first quote above I read "..substitution ... results in an
invalid type ..." not "...substitution ... *of* ... invalid type ...".
Hence IIUC como is right here.
enum { unnamed };
template < int i > int value() { return i; }
int main() { value< unnamed >(); }
The above is Ok as substitution doesent result in an invalid type.
(I mention this as it appears to be a case where you can use an
anonymous enum with templates - I wasn't sure it was possible .
Where as this:
template < typename T > stuct name {};
template < typename T> name< T > named( T const &v )
{
return name< T >();
}
does, the invalid type being name< hasnt-got-a-type-name >. But it
will never get this far as the substitution T = hasnt-got-a-type-name
is illegal, as T must be a type-name with external linkage. "unnamed"
above has neither of these (a type-name or external linkage).
Thanks for bring this up BTW. I'd read something about problems with
anonymous enum's, but it was a aside in a post about something else
so I never really got it till now. Since then I've been happlesly
coding enum give_it_a_name { Whatever }; just-in-case, without
understanding why .
Rob.
--
http://www.victim-prime.dsl.pipex.com/
|
|
| Back to top |
|
 |
tom_usenet Guest
|
Posted: Wed Oct 29, 2003 3:30 pm Post subject: Re: overload resolution / integral promotion / standard |
|
|
On Wed, 29 Oct 2003 16:10:45 +0100, Alexander Stippler
<stip (AT) mathematik (DOT) uni-ulm.de> wrote:
| Quote: | I think the standard is not very precise here. IMO a compiler should not
consider a template function in the given context, since it would have to
instantiate it with an unnamed type, what is not allowed. And the standard
says:
"Template arguments can be deduced in several different contexts, but in
each case a type that is specified in terms of template parameters(call it
P) is compared with an actual type (call it A). and an attempt is made to
find template argument values ( ... ) that will make P, after substitution
of the deduced values (call it the deduced A), compatible with A.
[14.8.2.4] IMO a compiler should therefore not try any unnamed type as
template parameter anyway in this process, since this does not make sense -
they are not allowed.
|
The parameter types are legal types though, it is only the template
instantiation that is illegal. The validity of the instantiation isn't
checked until later.
So why try them?
| Quote: | To me - independent of what the standard says - it would make sense to
handle it the way I proposed. What do you think?
|
There is a decent thread about this stuff here:
http://groups.google.co.uk/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=003401c1d1f3%24e61ddf20%247772e50c%40c161550a
Tom
|
|
| Back to top |
|
 |
Alexander Stippler Guest
|
Posted: Wed Oct 29, 2003 3:53 pm Post subject: Re: overload resolution / integral promotion / standard |
|
|
tom_usenet wrote:
I'm afraid, you're right in terms of the standard. But considering 'normal
human logic', why does it make sense for a compiler to instantiate template
parameters with unnamed types during overload resolution, knowing exactly
that this can never result in valid code? In other words: If there are
alternatives to such a candidate function, why does it make sense that a
compiler quits the compilation process with an error message, if it would
only have had to ignore some (not instatiatable) candidate, what would btw
decrease compile time a bit, too?
regards,
alex
|
|
| Back to top |
|
 |
Rolf Magnus Guest
|
Posted: Thu Oct 30, 2003 10:47 am Post subject: Re: overload resolution / integral promotion / standard |
|
|
Alexander Stippler wrote:
| Quote: | Hi,
I have got a question concerning the overload resolution rules of C++
and enumeration types. The following little test program illustrates
the situation:
enum { red, green, blue };
template
A
operator+(const A &a, const B& b)
{
return a;
}
int
main()
{
int i = 0;
i = i + green;
return 0;
}
The code does not really make much sense, but illustrates my problem:
I would never have guessed that every compiler I tried uses the
template operator+ instead of a builtin +.
|
You can overload operators for enum types just the same as for classes
(13.5p6), so your overloaded template operator gets called for it.
| Quote: | IMO the compiler has to prefer the builtin + according to the
standard:
1) both the user-defined + and the builtin + are in the candidate set.
[13.3.1/13.3.2] and [13.6.2/13.6.12].
2) both are viable.
3) but the built-in + is better [13.3.3].
By the way, I have neglected the fact, that the enum is an unnamed
type, so that the compiler should not choose the template version
anyway (or should it?)
|
Why should there be any difference between a named and an unnamed enum
type?
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|