overload resolution / integral promotion / standard

Discussion in 'C++' started by Alexander Stippler, Oct 29, 2003.

  1. 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
    Alexander Stippler, Oct 29, 2003
    #1
    1. Advertising

  2. Alexander Stippler wrote in news:-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+(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.

    >
    > 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
    "Substitution Failure", hence it doesn't select the builtin op +
    anyway.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
    Rob Williscroft, Oct 29, 2003
    #2
    1. Advertising

  3. Rolf Magnus wrote in news:bno9fc$sf5$07$-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/
    Rob Williscroft, Oct 29, 2003
    #3
  4. Rob Williscroft wrote:


    >>
    >> 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;
    >> }
    >>
    >>


    >
    > 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
    Alexander Stippler, Oct 29, 2003
    #4
  5. Alexander Stippler

    tom_usenet Guest

    On Wed, 29 Oct 2003 13:58:37 +0100, Alexander Stippler
    <-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
    tom_usenet, Oct 29, 2003
    #5
  6. tom_usenet wrote:

    > On Wed, 29 Oct 2003 13:58:37 +0100, Alexander Stippler
    > <-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
    Alexander Stippler, Oct 29, 2003
    #6
  7. Alexander Stippler

    Rolf Magnus Guest

    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?
    Rolf Magnus, Oct 30, 2003
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Niels Dekker (no reply address)

    Usual arithmetic conversions + integral promotion for short?

    Niels Dekker (no reply address), May 19, 2004, in forum: C++
    Replies:
    10
    Views:
    1,918
    Niels Dekker (no reply address)
    May 22, 2004
  2. Fred Ma
    Replies:
    9
    Views:
    397
    Dave Thompson
    Feb 9, 2004
  3. Carsten Hansen

    Bit-fields and integral promotion

    Carsten Hansen, Jan 28, 2005, in forum: C Programming
    Replies:
    117
    Views:
    1,925
    Joe Wright
    Feb 8, 2005
  4. TTroy
    Replies:
    16
    Views:
    787
    Peter Nilsson
    Jan 31, 2005
  5. Christian Kandeler

    Bit-fields and integral promotion/UACs

    Christian Kandeler, Jan 27, 2006, in forum: C Programming
    Replies:
    10
    Views:
    676
    Alex Fraser
    Jan 28, 2006
Loading...

Share This Page