Overload pure virtual function with non pure virtual version

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











up vote
7
down vote

favorite












With Base and Derived defined like this:



class Base 

public:
virtual int f1(int a) const = 0;
virtual int f2(int a, int b) const return a+b;
;

class Derived : public Base

public:
int f1(int a) const return a;
;

int main()
Derived obj;
cout << obj.f1(1) << endl;
cout << obj.f2(1, 2) << endl;



The result is



1
3


obj.f1(1) uses the f1 implementation from Derived and obj.f2(1, 2) uses the implementation inherited from Base, which is what I want.



Now, I would like these two functions to have the same name, f, so the base class provides an implementation when there are two parameters and the derived class must implement the single parameter version (that's why it's pure virtual).



However, if I do this (just rename f1 and f2 to f):



class Base 

public:
virtual int f(int a) const = 0;
virtual int f(int a, int b) const return a + b;
;

class Derived : public Base

public:
int f(int a) const return a;
;

int main()
Derived obj;
cout << obj.f(1) << endl;
cout << obj.f(1, 2) << endl;



I get the following error:



20:23: error: no matching function for call to 'Derived::f(int, int)'
20:23: note: candidate is:
14:13: note: virtual int Derived::f(int) const
14:13: note: candidate expects 1 argument, 2 provided


Why is this? Is it not possible to do this kind of overloading?










share|improve this question

























    up vote
    7
    down vote

    favorite












    With Base and Derived defined like this:



    class Base 

    public:
    virtual int f1(int a) const = 0;
    virtual int f2(int a, int b) const return a+b;
    ;

    class Derived : public Base

    public:
    int f1(int a) const return a;
    ;

    int main()
    Derived obj;
    cout << obj.f1(1) << endl;
    cout << obj.f2(1, 2) << endl;



    The result is



    1
    3


    obj.f1(1) uses the f1 implementation from Derived and obj.f2(1, 2) uses the implementation inherited from Base, which is what I want.



    Now, I would like these two functions to have the same name, f, so the base class provides an implementation when there are two parameters and the derived class must implement the single parameter version (that's why it's pure virtual).



    However, if I do this (just rename f1 and f2 to f):



    class Base 

    public:
    virtual int f(int a) const = 0;
    virtual int f(int a, int b) const return a + b;
    ;

    class Derived : public Base

    public:
    int f(int a) const return a;
    ;

    int main()
    Derived obj;
    cout << obj.f(1) << endl;
    cout << obj.f(1, 2) << endl;



    I get the following error:



    20:23: error: no matching function for call to 'Derived::f(int, int)'
    20:23: note: candidate is:
    14:13: note: virtual int Derived::f(int) const
    14:13: note: candidate expects 1 argument, 2 provided


    Why is this? Is it not possible to do this kind of overloading?










    share|improve this question























      up vote
      7
      down vote

      favorite









      up vote
      7
      down vote

      favorite











      With Base and Derived defined like this:



      class Base 

      public:
      virtual int f1(int a) const = 0;
      virtual int f2(int a, int b) const return a+b;
      ;

      class Derived : public Base

      public:
      int f1(int a) const return a;
      ;

      int main()
      Derived obj;
      cout << obj.f1(1) << endl;
      cout << obj.f2(1, 2) << endl;



      The result is



      1
      3


      obj.f1(1) uses the f1 implementation from Derived and obj.f2(1, 2) uses the implementation inherited from Base, which is what I want.



      Now, I would like these two functions to have the same name, f, so the base class provides an implementation when there are two parameters and the derived class must implement the single parameter version (that's why it's pure virtual).



      However, if I do this (just rename f1 and f2 to f):



      class Base 

      public:
      virtual int f(int a) const = 0;
      virtual int f(int a, int b) const return a + b;
      ;

      class Derived : public Base

      public:
      int f(int a) const return a;
      ;

      int main()
      Derived obj;
      cout << obj.f(1) << endl;
      cout << obj.f(1, 2) << endl;



      I get the following error:



      20:23: error: no matching function for call to 'Derived::f(int, int)'
      20:23: note: candidate is:
      14:13: note: virtual int Derived::f(int) const
      14:13: note: candidate expects 1 argument, 2 provided


      Why is this? Is it not possible to do this kind of overloading?










      share|improve this question













      With Base and Derived defined like this:



      class Base 

      public:
      virtual int f1(int a) const = 0;
      virtual int f2(int a, int b) const return a+b;
      ;

      class Derived : public Base

      public:
      int f1(int a) const return a;
      ;

      int main()
      Derived obj;
      cout << obj.f1(1) << endl;
      cout << obj.f2(1, 2) << endl;



      The result is



      1
      3


      obj.f1(1) uses the f1 implementation from Derived and obj.f2(1, 2) uses the implementation inherited from Base, which is what I want.



      Now, I would like these two functions to have the same name, f, so the base class provides an implementation when there are two parameters and the derived class must implement the single parameter version (that's why it's pure virtual).



      However, if I do this (just rename f1 and f2 to f):



      class Base 

      public:
      virtual int f(int a) const = 0;
      virtual int f(int a, int b) const return a + b;
      ;

      class Derived : public Base

      public:
      int f(int a) const return a;
      ;

      int main()
      Derived obj;
      cout << obj.f(1) << endl;
      cout << obj.f(1, 2) << endl;



      I get the following error:



      20:23: error: no matching function for call to 'Derived::f(int, int)'
      20:23: note: candidate is:
      14:13: note: virtual int Derived::f(int) const
      14:13: note: candidate expects 1 argument, 2 provided


      Why is this? Is it not possible to do this kind of overloading?







      c++






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 46 mins ago









      Milo

      1,031926




      1,031926






















          5 Answers
          5






          active

          oldest

          votes

















          up vote
          7
          down vote













          You need to write



          class Derived : public Base 

          public:
          using Base::f;
          int f(int a) const return a;
          ;


          Note the using statement. That brings the base class version back into scope.






          share|improve this answer



























            up vote
            3
            down vote













            Go to the concise answer by @Bathsheba to see the proper way at solving the issue -- I'm just putting this here to answer the question:




            Why is this? Is it not possible to do this kind of overloading?




            No, not possible as written in the original question due to [basic.scope.hiding¶3]:




            In a member function definition, the declaration of a name at block
            scope hides the declaration of a member of the class with the same
            name; see [basic.scope.class]. The declaration of a member in a
            derived class hides the declaration of a member of a base class of the
            same name;
            see [class.member.lookup].




            This clause is about names, not overloads. As such, it doesn't matter if there are other overloads in the base class, they all share the same name, which is hidden according to quote above.






            share|improve this answer





























              up vote
              1
              down vote













              You can either pull all definitions of Base into scope with by writing using Base::f; or you can explcitily write for some versions of f something like this: int f(int a, int b) const override return Base::f(a,b);



              class Derived : public Base 

              public:
              int f(int a) const return a;
              int f(int a, int b) const override return Base::f(a,b);
              ;


              The version with using is already mentioned in this answer:



              class Derived : public Base 

              public:
              using Base::f;
              int f(int a) const return a;
              ;


              Note: I know that the second version does not work on MSVC 2010. I am also aware this compiler is ancient, but just for people who care ;)






              share|improve this answer





























                up vote
                0
                down vote













                In addition to the other solutions, if you don't want to redefine f you could explicitly invoke f of the base class using



                int main() 
                Derived obj;
                cout << obj.f1(1) << endl;
                cout << obj.Base::f2(1, 2) << endl;





                share



























                  up vote
                  0
                  down vote














                  Why is this?




                  Calling one of multiple overloads of a member function is resolved by the compiler during "overload resolution". But before available overloads can be evaluated with respect to how well they match the invocation, they must be collected. This step is the "name lookup". Here,



                  cout << obj.f(1, 2) << endl;


                  the static type of the instance obj, which is Derived, is searched for a function signature with the name f. There is exactly one, because once any f has been overridden, this is the only interface Derived offers its clients. Those from Base are not automatically brought in - but why this limitation?



                  Think of an overload set as a bundled entity of a class interface. Base offers an overload set Base::f, and Derived offers Derived::f. Again, once one single function of the former overrides one function of the latter, the whole overload set is overridden (unless enriched by using Base::f). This makes sense, because f (the overload set) is the means a class designer gives client code to use its class.






                  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%2f52364745%2foverload-pure-virtual-function-with-non-pure-virtual-version%23new-answer', 'question_page');

                    );

                    Post as a guest






























                    5 Answers
                    5






                    active

                    oldest

                    votes








                    5 Answers
                    5






                    active

                    oldest

                    votes









                    active

                    oldest

                    votes






                    active

                    oldest

                    votes








                    up vote
                    7
                    down vote













                    You need to write



                    class Derived : public Base 

                    public:
                    using Base::f;
                    int f(int a) const return a;
                    ;


                    Note the using statement. That brings the base class version back into scope.






                    share|improve this answer
























                      up vote
                      7
                      down vote













                      You need to write



                      class Derived : public Base 

                      public:
                      using Base::f;
                      int f(int a) const return a;
                      ;


                      Note the using statement. That brings the base class version back into scope.






                      share|improve this answer






















                        up vote
                        7
                        down vote










                        up vote
                        7
                        down vote









                        You need to write



                        class Derived : public Base 

                        public:
                        using Base::f;
                        int f(int a) const return a;
                        ;


                        Note the using statement. That brings the base class version back into scope.






                        share|improve this answer












                        You need to write



                        class Derived : public Base 

                        public:
                        using Base::f;
                        int f(int a) const return a;
                        ;


                        Note the using statement. That brings the base class version back into scope.







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered 45 mins ago









                        Bathsheba

                        167k26237352




                        167k26237352






















                            up vote
                            3
                            down vote













                            Go to the concise answer by @Bathsheba to see the proper way at solving the issue -- I'm just putting this here to answer the question:




                            Why is this? Is it not possible to do this kind of overloading?




                            No, not possible as written in the original question due to [basic.scope.hiding¶3]:




                            In a member function definition, the declaration of a name at block
                            scope hides the declaration of a member of the class with the same
                            name; see [basic.scope.class]. The declaration of a member in a
                            derived class hides the declaration of a member of a base class of the
                            same name;
                            see [class.member.lookup].




                            This clause is about names, not overloads. As such, it doesn't matter if there are other overloads in the base class, they all share the same name, which is hidden according to quote above.






                            share|improve this answer


























                              up vote
                              3
                              down vote













                              Go to the concise answer by @Bathsheba to see the proper way at solving the issue -- I'm just putting this here to answer the question:




                              Why is this? Is it not possible to do this kind of overloading?




                              No, not possible as written in the original question due to [basic.scope.hiding¶3]:




                              In a member function definition, the declaration of a name at block
                              scope hides the declaration of a member of the class with the same
                              name; see [basic.scope.class]. The declaration of a member in a
                              derived class hides the declaration of a member of a base class of the
                              same name;
                              see [class.member.lookup].




                              This clause is about names, not overloads. As such, it doesn't matter if there are other overloads in the base class, they all share the same name, which is hidden according to quote above.






                              share|improve this answer
























                                up vote
                                3
                                down vote










                                up vote
                                3
                                down vote









                                Go to the concise answer by @Bathsheba to see the proper way at solving the issue -- I'm just putting this here to answer the question:




                                Why is this? Is it not possible to do this kind of overloading?




                                No, not possible as written in the original question due to [basic.scope.hiding¶3]:




                                In a member function definition, the declaration of a name at block
                                scope hides the declaration of a member of the class with the same
                                name; see [basic.scope.class]. The declaration of a member in a
                                derived class hides the declaration of a member of a base class of the
                                same name;
                                see [class.member.lookup].




                                This clause is about names, not overloads. As such, it doesn't matter if there are other overloads in the base class, they all share the same name, which is hidden according to quote above.






                                share|improve this answer














                                Go to the concise answer by @Bathsheba to see the proper way at solving the issue -- I'm just putting this here to answer the question:




                                Why is this? Is it not possible to do this kind of overloading?




                                No, not possible as written in the original question due to [basic.scope.hiding¶3]:




                                In a member function definition, the declaration of a name at block
                                scope hides the declaration of a member of the class with the same
                                name; see [basic.scope.class]. The declaration of a member in a
                                derived class hides the declaration of a member of a base class of the
                                same name;
                                see [class.member.lookup].




                                This clause is about names, not overloads. As such, it doesn't matter if there are other overloads in the base class, they all share the same name, which is hidden according to quote above.







                                share|improve this answer














                                share|improve this answer



                                share|improve this answer








                                edited 12 mins ago









                                StoryTeller

                                82.9k12166230




                                82.9k12166230










                                answered 18 mins ago









                                SkepticalEmpiricist

                                3,473720




                                3,473720




















                                    up vote
                                    1
                                    down vote













                                    You can either pull all definitions of Base into scope with by writing using Base::f; or you can explcitily write for some versions of f something like this: int f(int a, int b) const override return Base::f(a,b);



                                    class Derived : public Base 

                                    public:
                                    int f(int a) const return a;
                                    int f(int a, int b) const override return Base::f(a,b);
                                    ;


                                    The version with using is already mentioned in this answer:



                                    class Derived : public Base 

                                    public:
                                    using Base::f;
                                    int f(int a) const return a;
                                    ;


                                    Note: I know that the second version does not work on MSVC 2010. I am also aware this compiler is ancient, but just for people who care ;)






                                    share|improve this answer


























                                      up vote
                                      1
                                      down vote













                                      You can either pull all definitions of Base into scope with by writing using Base::f; or you can explcitily write for some versions of f something like this: int f(int a, int b) const override return Base::f(a,b);



                                      class Derived : public Base 

                                      public:
                                      int f(int a) const return a;
                                      int f(int a, int b) const override return Base::f(a,b);
                                      ;


                                      The version with using is already mentioned in this answer:



                                      class Derived : public Base 

                                      public:
                                      using Base::f;
                                      int f(int a) const return a;
                                      ;


                                      Note: I know that the second version does not work on MSVC 2010. I am also aware this compiler is ancient, but just for people who care ;)






                                      share|improve this answer
























                                        up vote
                                        1
                                        down vote










                                        up vote
                                        1
                                        down vote









                                        You can either pull all definitions of Base into scope with by writing using Base::f; or you can explcitily write for some versions of f something like this: int f(int a, int b) const override return Base::f(a,b);



                                        class Derived : public Base 

                                        public:
                                        int f(int a) const return a;
                                        int f(int a, int b) const override return Base::f(a,b);
                                        ;


                                        The version with using is already mentioned in this answer:



                                        class Derived : public Base 

                                        public:
                                        using Base::f;
                                        int f(int a) const return a;
                                        ;


                                        Note: I know that the second version does not work on MSVC 2010. I am also aware this compiler is ancient, but just for people who care ;)






                                        share|improve this answer














                                        You can either pull all definitions of Base into scope with by writing using Base::f; or you can explcitily write for some versions of f something like this: int f(int a, int b) const override return Base::f(a,b);



                                        class Derived : public Base 

                                        public:
                                        int f(int a) const return a;
                                        int f(int a, int b) const override return Base::f(a,b);
                                        ;


                                        The version with using is already mentioned in this answer:



                                        class Derived : public Base 

                                        public:
                                        using Base::f;
                                        int f(int a) const return a;
                                        ;


                                        Note: I know that the second version does not work on MSVC 2010. I am also aware this compiler is ancient, but just for people who care ;)







                                        share|improve this answer














                                        share|improve this answer



                                        share|improve this answer








                                        edited 31 mins ago

























                                        answered 38 mins ago









                                        P i

                                        2,340832




                                        2,340832




















                                            up vote
                                            0
                                            down vote













                                            In addition to the other solutions, if you don't want to redefine f you could explicitly invoke f of the base class using



                                            int main() 
                                            Derived obj;
                                            cout << obj.f1(1) << endl;
                                            cout << obj.Base::f2(1, 2) << endl;





                                            share
























                                              up vote
                                              0
                                              down vote













                                              In addition to the other solutions, if you don't want to redefine f you could explicitly invoke f of the base class using



                                              int main() 
                                              Derived obj;
                                              cout << obj.f1(1) << endl;
                                              cout << obj.Base::f2(1, 2) << endl;





                                              share






















                                                up vote
                                                0
                                                down vote










                                                up vote
                                                0
                                                down vote









                                                In addition to the other solutions, if you don't want to redefine f you could explicitly invoke f of the base class using



                                                int main() 
                                                Derived obj;
                                                cout << obj.f1(1) << endl;
                                                cout << obj.Base::f2(1, 2) << endl;





                                                share












                                                In addition to the other solutions, if you don't want to redefine f you could explicitly invoke f of the base class using



                                                int main() 
                                                Derived obj;
                                                cout << obj.f1(1) << endl;
                                                cout << obj.Base::f2(1, 2) << endl;






                                                share











                                                share


                                                share










                                                answered 2 mins ago









                                                dan

                                                1462




                                                1462




















                                                    up vote
                                                    0
                                                    down vote














                                                    Why is this?




                                                    Calling one of multiple overloads of a member function is resolved by the compiler during "overload resolution". But before available overloads can be evaluated with respect to how well they match the invocation, they must be collected. This step is the "name lookup". Here,



                                                    cout << obj.f(1, 2) << endl;


                                                    the static type of the instance obj, which is Derived, is searched for a function signature with the name f. There is exactly one, because once any f has been overridden, this is the only interface Derived offers its clients. Those from Base are not automatically brought in - but why this limitation?



                                                    Think of an overload set as a bundled entity of a class interface. Base offers an overload set Base::f, and Derived offers Derived::f. Again, once one single function of the former overrides one function of the latter, the whole overload set is overridden (unless enriched by using Base::f). This makes sense, because f (the overload set) is the means a class designer gives client code to use its class.






                                                    share|improve this answer


























                                                      up vote
                                                      0
                                                      down vote














                                                      Why is this?




                                                      Calling one of multiple overloads of a member function is resolved by the compiler during "overload resolution". But before available overloads can be evaluated with respect to how well they match the invocation, they must be collected. This step is the "name lookup". Here,



                                                      cout << obj.f(1, 2) << endl;


                                                      the static type of the instance obj, which is Derived, is searched for a function signature with the name f. There is exactly one, because once any f has been overridden, this is the only interface Derived offers its clients. Those from Base are not automatically brought in - but why this limitation?



                                                      Think of an overload set as a bundled entity of a class interface. Base offers an overload set Base::f, and Derived offers Derived::f. Again, once one single function of the former overrides one function of the latter, the whole overload set is overridden (unless enriched by using Base::f). This makes sense, because f (the overload set) is the means a class designer gives client code to use its class.






                                                      share|improve this answer
























                                                        up vote
                                                        0
                                                        down vote










                                                        up vote
                                                        0
                                                        down vote










                                                        Why is this?




                                                        Calling one of multiple overloads of a member function is resolved by the compiler during "overload resolution". But before available overloads can be evaluated with respect to how well they match the invocation, they must be collected. This step is the "name lookup". Here,



                                                        cout << obj.f(1, 2) << endl;


                                                        the static type of the instance obj, which is Derived, is searched for a function signature with the name f. There is exactly one, because once any f has been overridden, this is the only interface Derived offers its clients. Those from Base are not automatically brought in - but why this limitation?



                                                        Think of an overload set as a bundled entity of a class interface. Base offers an overload set Base::f, and Derived offers Derived::f. Again, once one single function of the former overrides one function of the latter, the whole overload set is overridden (unless enriched by using Base::f). This makes sense, because f (the overload set) is the means a class designer gives client code to use its class.






                                                        share|improve this answer















                                                        Why is this?




                                                        Calling one of multiple overloads of a member function is resolved by the compiler during "overload resolution". But before available overloads can be evaluated with respect to how well they match the invocation, they must be collected. This step is the "name lookup". Here,



                                                        cout << obj.f(1, 2) << endl;


                                                        the static type of the instance obj, which is Derived, is searched for a function signature with the name f. There is exactly one, because once any f has been overridden, this is the only interface Derived offers its clients. Those from Base are not automatically brought in - but why this limitation?



                                                        Think of an overload set as a bundled entity of a class interface. Base offers an overload set Base::f, and Derived offers Derived::f. Again, once one single function of the former overrides one function of the latter, the whole overload set is overridden (unless enriched by using Base::f). This makes sense, because f (the overload set) is the means a class designer gives client code to use its class.







                                                        share|improve this answer














                                                        share|improve this answer



                                                        share|improve this answer








                                                        edited 1 min ago

























                                                        answered 21 mins ago









                                                        lubgr

                                                        6,59021340




                                                        6,59021340



























                                                             

                                                            draft saved


                                                            draft discarded















































                                                             


                                                            draft saved


                                                            draft discarded














                                                            StackExchange.ready(
                                                            function ()
                                                            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52364745%2foverload-pure-virtual-function-with-non-pure-virtual-version%23new-answer', 'question_page');

                                                            );

                                                            Post as a guest













































































                                                            Comments

                                                            Popular posts from this blog

                                                            What does second last employer means? [closed]

                                                            List of Gilmore Girls characters

                                                            Confectionery