473,563 Members | 2,797 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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
Jul 19 '05 #1
9 2736
Alexander Stippler wrote:
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 +.
You can overload operators for enum types just the same as for classes
(13.5p6), so your overloaded template operator gets called for it.
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?

Jul 19 '05 #2
Alexander Stippler wrote in news:3f******@n ews.uni-ulm.de:
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+(cons t 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.

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 <class A, class B>
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
"Substituti on Failure", hence it doesn't select the builtin op +
anyway.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 19 '05 #3
Rolf Magnus wrote in news:bn******** *****@news.t-online.com:
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, <unnamed-type> >( A const &, <unnamed-type> const &).

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 19 '05 #4
Rob Williscroft wrote:


enum { red, green, blue };
template <class A, class B>
A
operator+(con st 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
Jul 19 '05 #5
On Wed, 29 Oct 2003 13:58:37 +0100, Alexander Stippler
<st**@mathemati k.uni-ulm.de> 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
Jul 19 '05 #6
tom_usenet wrote:
On Wed, 29 Oct 2003 13:58:37 +0100, Alexander Stippler
<st**@mathemati k.uni-ulm.de> 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
Jul 19 '05 #7
Alexander Stippler wrote in news:3f******@n ews.uni-ulm.de:
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 "..substitu tion ... results in an
invalid type ..." not "...substitutio n ... *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/
Jul 19 '05 #8
On Wed, 29 Oct 2003 16:10:45 +0100, Alexander Stippler
<st**@mathemati k.uni-ulm.de> wrote:
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?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...50c%40c161550a

Tom
Jul 19 '05 #9
tom_usenet wrote:

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?
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...50c%40c161550a
Tom


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
Jul 19 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
1570
by: David Sachs | last post by:
The following program illustrates an interesting effect of the way C++ resolves function overloading. I have verified with a member of the C++ stardard committee that the output shown is correct. *********************************Program******************************** #include <iostream> using std::cout;
10
2249
by: Niels Dekker (no reply address) | last post by:
Is it possible for a standard compliant C++ compiler to have ( sizeof(short) < sizeof(int) ) and ( sizeof(short) == sizeof((short)0 + (short)0) ) ? Regards, Niels Dekker http://www.xs4all.nl/~nd/dekkerware
9
4945
by: Fred Ma | last post by:
Hello, I've been trying to clear up a confusion about integer promotions during expression evaluation. I've checked the C FAQ and C++ FAQ (they are different languages, but I was hoping one would clear up the confusion), as well as googling groups and the web. The confusion is that for a binary operator,
112
4307
by: Carsten Hansen | last post by:
Suppose I'm using an implementation where an int is 16 bits. In the program below, what function is called in the first case, and what is called in the second case? Also, if there is a difference between C89 and C99, I would like to know. I have tried with different compilers, and I see some differences. Before I file a bug report with my C...
16
5106
by: TTroy | last post by:
Hello, I'm relatively new to C and have gone through more than 4 books on it. None mentioned anything about integral promotion, arithmetic conversion, value preserving and unsigned preserving. And K&R2 mentions "signed extension" everywhere. Reading some old clc posts, I've beginning to realize that these books are over-generalizing the...
2
1439
by: sri | last post by:
class Base { public: virtual void f(int) { std::cout<<"base.f(int)\n";}; virtual void f(std::complex<double>) { std::cout<<"derived.f \n"; }; }; class Derived : public Base {
14
2119
by: Thurston Manson | last post by:
Suppose I'm using an implementation where an int is 16 bits. In the program below, what function is called in the first case, and what is called in the second case? Also, if there is a difference between C89 and C99, I would like to know. I have tried with different compilers, and I see some differences. Before I file a bug report with my...
2
1858
by: xtrigger303 | last post by:
Hi to all, I was reading Mr. Alexandrescu's mojo article and I've a hard time understanding the following. Let's suppose I have: //code struct A {}; struct B : A {};
5
3679
by: jknupp | last post by:
In the following program, if the call to bar does not specify the type as <int>, gcc gives the error "no matching function for call to ‘bar(A&, <unresolved overloaded function type>)’". Since bar explicitly takes a pointer-to-member with no parameters, why is the lookup for the overloaded function not able to use the number of arguments to...
0
7583
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7888
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
1
7642
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
6255
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
5213
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3643
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3626
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2082
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
0
924
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.