Why is overriding both the global new operator and the class-specific operator not ambiguous behaviour?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
8
down vote

favorite












Consider the following code:



class Foo 

public:
//class-specific
Foo operator+(Foo& rhs)

return Foo(); //Just return a temporary


void* operator new(size_t sd)

return malloc(sd);

;

//global
Foo operator+(Foo& lhs, Foo& rhs)

return Foo();


void* operator new(size_t sd)

return malloc(sd);



This code will not compile, stating the call is ambiguous because it matches two operators:



Foo a, b;
a + b;


But this one with the new operator compiles just fine, and will call the class-specific one.



Foo* a = new Foo();


Why doesn't it result in a compile error? Does the compiler treat the new operator differently? (Any citation to the standard would be appreciated.)










share|improve this question



























    up vote
    8
    down vote

    favorite












    Consider the following code:



    class Foo 

    public:
    //class-specific
    Foo operator+(Foo& rhs)

    return Foo(); //Just return a temporary


    void* operator new(size_t sd)

    return malloc(sd);

    ;

    //global
    Foo operator+(Foo& lhs, Foo& rhs)

    return Foo();


    void* operator new(size_t sd)

    return malloc(sd);



    This code will not compile, stating the call is ambiguous because it matches two operators:



    Foo a, b;
    a + b;


    But this one with the new operator compiles just fine, and will call the class-specific one.



    Foo* a = new Foo();


    Why doesn't it result in a compile error? Does the compiler treat the new operator differently? (Any citation to the standard would be appreciated.)










    share|improve this question

























      up vote
      8
      down vote

      favorite









      up vote
      8
      down vote

      favorite











      Consider the following code:



      class Foo 

      public:
      //class-specific
      Foo operator+(Foo& rhs)

      return Foo(); //Just return a temporary


      void* operator new(size_t sd)

      return malloc(sd);

      ;

      //global
      Foo operator+(Foo& lhs, Foo& rhs)

      return Foo();


      void* operator new(size_t sd)

      return malloc(sd);



      This code will not compile, stating the call is ambiguous because it matches two operators:



      Foo a, b;
      a + b;


      But this one with the new operator compiles just fine, and will call the class-specific one.



      Foo* a = new Foo();


      Why doesn't it result in a compile error? Does the compiler treat the new operator differently? (Any citation to the standard would be appreciated.)










      share|improve this question















      Consider the following code:



      class Foo 

      public:
      //class-specific
      Foo operator+(Foo& rhs)

      return Foo(); //Just return a temporary


      void* operator new(size_t sd)

      return malloc(sd);

      ;

      //global
      Foo operator+(Foo& lhs, Foo& rhs)

      return Foo();


      void* operator new(size_t sd)

      return malloc(sd);



      This code will not compile, stating the call is ambiguous because it matches two operators:



      Foo a, b;
      a + b;


      But this one with the new operator compiles just fine, and will call the class-specific one.



      Foo* a = new Foo();


      Why doesn't it result in a compile error? Does the compiler treat the new operator differently? (Any citation to the standard would be appreciated.)







      c++ c++11 c++14 language-lawyer new-operator






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 52 mins ago









      Boann

      35.8k1185116




      35.8k1185116










      asked 3 hours ago









      A. S.

      10918




      10918






















          3 Answers
          3






          active

          oldest

          votes

















          up vote
          4
          down vote



          accepted











          Why doesn't it result in a compile error? Does the compiler treat the new operator differently? (Any citation to the standard would be appreciated)




          Regarding the precedence between global new and class specific new, the reference says this:




          As described in allocation function, the C++ program may provide global and class-specific replacements for these functions. If the new-expression begins with the optional :: operator, as in ::new T or ::new T[n], class-specific replacements will be ignored (the function is looked up in global scope). Otherwise, if T is a class type, lookup begins in the class scope of T.




          So class specific new has priority.



          Regarding the overload of +, you can either have the member overload or the global overload (usually as a friend of the class) but not both because of the ambiguity it produces.






          share|improve this answer





























            up vote
            4
            down vote













            The class' operator new is always preferred if defined:




            [expr.new]/9



            If the new-expression begins with a unary ​::​ operator, the allocation function's name is looked up in the global scope. Otherwise, if the allocated type is a class type T or array thereof, the allocation function's name is looked up in the scope of T. If this lookup fails to find the name, or if the allocated type is not a class type, the allocation function's name is looked up in the global scope.




            It can be tricky to read: if the new-expression does not begins with :: and the allocated type is a class type, then new is looked up in the class' scope.






            share|improve this answer





























              up vote
              3
              down vote













              Your global new operator has no direct relation to the class Foo. A class specific new has precedence over the global new. There is no ambiguity.



              Your operator+ does specifically relate to the class Foo. There is no precedence between the operator defined outside and the one defined inside the class. Thus you get ambiguity.






              share|improve this answer




















                Your Answer





                StackExchange.ifUsing("editor", function ()
                StackExchange.using("externalEditor", function ()
                StackExchange.using("snippets", function ()
                StackExchange.snippets.init();
                );
                );
                , "code-snippets");

                StackExchange.ready(function()
                var channelOptions =
                tags: "".split(" "),
                id: "1"
                ;
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function()
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled)
                StackExchange.using("snippets", function()
                createEditor();
                );

                else
                createEditor();

                );

                function createEditor()
                StackExchange.prepareEditor(
                heartbeatType: 'answer',
                convertImagesToLinks: true,
                noModals: false,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: 10,
                bindNavPrevention: true,
                postfix: "",
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                );



                );













                 

                draft saved


                draft discarded


















                StackExchange.ready(
                function ()
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52554571%2fwhy-is-overriding-both-the-global-new-operator-and-the-class-specific-operator-n%23new-answer', 'question_page');

                );

                Post as a guest






























                3 Answers
                3






                active

                oldest

                votes








                3 Answers
                3






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes








                up vote
                4
                down vote



                accepted











                Why doesn't it result in a compile error? Does the compiler treat the new operator differently? (Any citation to the standard would be appreciated)




                Regarding the precedence between global new and class specific new, the reference says this:




                As described in allocation function, the C++ program may provide global and class-specific replacements for these functions. If the new-expression begins with the optional :: operator, as in ::new T or ::new T[n], class-specific replacements will be ignored (the function is looked up in global scope). Otherwise, if T is a class type, lookup begins in the class scope of T.




                So class specific new has priority.



                Regarding the overload of +, you can either have the member overload or the global overload (usually as a friend of the class) but not both because of the ambiguity it produces.






                share|improve this answer


























                  up vote
                  4
                  down vote



                  accepted











                  Why doesn't it result in a compile error? Does the compiler treat the new operator differently? (Any citation to the standard would be appreciated)




                  Regarding the precedence between global new and class specific new, the reference says this:




                  As described in allocation function, the C++ program may provide global and class-specific replacements for these functions. If the new-expression begins with the optional :: operator, as in ::new T or ::new T[n], class-specific replacements will be ignored (the function is looked up in global scope). Otherwise, if T is a class type, lookup begins in the class scope of T.




                  So class specific new has priority.



                  Regarding the overload of +, you can either have the member overload or the global overload (usually as a friend of the class) but not both because of the ambiguity it produces.






                  share|improve this answer
























                    up vote
                    4
                    down vote



                    accepted







                    up vote
                    4
                    down vote



                    accepted







                    Why doesn't it result in a compile error? Does the compiler treat the new operator differently? (Any citation to the standard would be appreciated)




                    Regarding the precedence between global new and class specific new, the reference says this:




                    As described in allocation function, the C++ program may provide global and class-specific replacements for these functions. If the new-expression begins with the optional :: operator, as in ::new T or ::new T[n], class-specific replacements will be ignored (the function is looked up in global scope). Otherwise, if T is a class type, lookup begins in the class scope of T.




                    So class specific new has priority.



                    Regarding the overload of +, you can either have the member overload or the global overload (usually as a friend of the class) but not both because of the ambiguity it produces.






                    share|improve this answer















                    Why doesn't it result in a compile error? Does the compiler treat the new operator differently? (Any citation to the standard would be appreciated)




                    Regarding the precedence between global new and class specific new, the reference says this:




                    As described in allocation function, the C++ program may provide global and class-specific replacements for these functions. If the new-expression begins with the optional :: operator, as in ::new T or ::new T[n], class-specific replacements will be ignored (the function is looked up in global scope). Otherwise, if T is a class type, lookup begins in the class scope of T.




                    So class specific new has priority.



                    Regarding the overload of +, you can either have the member overload or the global overload (usually as a friend of the class) but not both because of the ambiguity it produces.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited 2 hours ago

























                    answered 2 hours ago









                    P.W

                    3,702326




                    3,702326






















                        up vote
                        4
                        down vote













                        The class' operator new is always preferred if defined:




                        [expr.new]/9



                        If the new-expression begins with a unary ​::​ operator, the allocation function's name is looked up in the global scope. Otherwise, if the allocated type is a class type T or array thereof, the allocation function's name is looked up in the scope of T. If this lookup fails to find the name, or if the allocated type is not a class type, the allocation function's name is looked up in the global scope.




                        It can be tricky to read: if the new-expression does not begins with :: and the allocated type is a class type, then new is looked up in the class' scope.






                        share|improve this answer


























                          up vote
                          4
                          down vote













                          The class' operator new is always preferred if defined:




                          [expr.new]/9



                          If the new-expression begins with a unary ​::​ operator, the allocation function's name is looked up in the global scope. Otherwise, if the allocated type is a class type T or array thereof, the allocation function's name is looked up in the scope of T. If this lookup fails to find the name, or if the allocated type is not a class type, the allocation function's name is looked up in the global scope.




                          It can be tricky to read: if the new-expression does not begins with :: and the allocated type is a class type, then new is looked up in the class' scope.






                          share|improve this answer
























                            up vote
                            4
                            down vote










                            up vote
                            4
                            down vote









                            The class' operator new is always preferred if defined:




                            [expr.new]/9



                            If the new-expression begins with a unary ​::​ operator, the allocation function's name is looked up in the global scope. Otherwise, if the allocated type is a class type T or array thereof, the allocation function's name is looked up in the scope of T. If this lookup fails to find the name, or if the allocated type is not a class type, the allocation function's name is looked up in the global scope.




                            It can be tricky to read: if the new-expression does not begins with :: and the allocated type is a class type, then new is looked up in the class' scope.






                            share|improve this answer














                            The class' operator new is always preferred if defined:




                            [expr.new]/9



                            If the new-expression begins with a unary ​::​ operator, the allocation function's name is looked up in the global scope. Otherwise, if the allocated type is a class type T or array thereof, the allocation function's name is looked up in the scope of T. If this lookup fails to find the name, or if the allocated type is not a class type, the allocation function's name is looked up in the global scope.




                            It can be tricky to read: if the new-expression does not begins with :: and the allocated type is a class type, then new is looked up in the class' scope.







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited 2 hours ago

























                            answered 2 hours ago









                            YSC

                            17.5k34187




                            17.5k34187




















                                up vote
                                3
                                down vote













                                Your global new operator has no direct relation to the class Foo. A class specific new has precedence over the global new. There is no ambiguity.



                                Your operator+ does specifically relate to the class Foo. There is no precedence between the operator defined outside and the one defined inside the class. Thus you get ambiguity.






                                share|improve this answer
























                                  up vote
                                  3
                                  down vote













                                  Your global new operator has no direct relation to the class Foo. A class specific new has precedence over the global new. There is no ambiguity.



                                  Your operator+ does specifically relate to the class Foo. There is no precedence between the operator defined outside and the one defined inside the class. Thus you get ambiguity.






                                  share|improve this answer






















                                    up vote
                                    3
                                    down vote










                                    up vote
                                    3
                                    down vote









                                    Your global new operator has no direct relation to the class Foo. A class specific new has precedence over the global new. There is no ambiguity.



                                    Your operator+ does specifically relate to the class Foo. There is no precedence between the operator defined outside and the one defined inside the class. Thus you get ambiguity.






                                    share|improve this answer












                                    Your global new operator has no direct relation to the class Foo. A class specific new has precedence over the global new. There is no ambiguity.



                                    Your operator+ does specifically relate to the class Foo. There is no precedence between the operator defined outside and the one defined inside the class. Thus you get ambiguity.







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered 3 hours ago









                                    Max Vollmer

                                    5,45341337




                                    5,45341337



























                                         

                                        draft saved


                                        draft discarded















































                                         


                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function ()
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52554571%2fwhy-is-overriding-both-the-global-new-operator-and-the-class-specific-operator-n%23new-answer', 'question_page');

                                        );

                                        Post as a guest













































































                                        Comments

                                        Popular posts from this blog

                                        Long meetings (6-7 hours a day): Being “babysat” by supervisor

                                        Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

                                        Confectionery