Why is inheritance of a const/non-const function overload ambiguous?












12















I was trying to create two classes, the first with a non-const implementation of the functions, the second with a const implementation. Here is a small example:



class Base {
protected:
int some;
};

class A : public virtual Base {
const int& get() const {
return some;
}
};

class B : public virtual Base {
int& get() {
return some;
}
};

class C : public A, B {};

C test;
test.get(); // ambiguous


The call to the get function is ambiguous. No matter that the const version needs to match more requirements. (Calling get on const C is ambiguous as well, but there is one possible function to call.)
Is there a reason for such behaviour in the standard? Thanks!










share|improve this question









New contributor




6yry6e is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





















  • stackoverflow.com/questions/5103543/…

    – Jesper Juhl
    9 hours ago
















12















I was trying to create two classes, the first with a non-const implementation of the functions, the second with a const implementation. Here is a small example:



class Base {
protected:
int some;
};

class A : public virtual Base {
const int& get() const {
return some;
}
};

class B : public virtual Base {
int& get() {
return some;
}
};

class C : public A, B {};

C test;
test.get(); // ambiguous


The call to the get function is ambiguous. No matter that the const version needs to match more requirements. (Calling get on const C is ambiguous as well, but there is one possible function to call.)
Is there a reason for such behaviour in the standard? Thanks!










share|improve this question









New contributor




6yry6e is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





















  • stackoverflow.com/questions/5103543/…

    – Jesper Juhl
    9 hours ago














12












12








12


1






I was trying to create two classes, the first with a non-const implementation of the functions, the second with a const implementation. Here is a small example:



class Base {
protected:
int some;
};

class A : public virtual Base {
const int& get() const {
return some;
}
};

class B : public virtual Base {
int& get() {
return some;
}
};

class C : public A, B {};

C test;
test.get(); // ambiguous


The call to the get function is ambiguous. No matter that the const version needs to match more requirements. (Calling get on const C is ambiguous as well, but there is one possible function to call.)
Is there a reason for such behaviour in the standard? Thanks!










share|improve this question









New contributor




6yry6e is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












I was trying to create two classes, the first with a non-const implementation of the functions, the second with a const implementation. Here is a small example:



class Base {
protected:
int some;
};

class A : public virtual Base {
const int& get() const {
return some;
}
};

class B : public virtual Base {
int& get() {
return some;
}
};

class C : public A, B {};

C test;
test.get(); // ambiguous


The call to the get function is ambiguous. No matter that the const version needs to match more requirements. (Calling get on const C is ambiguous as well, but there is one possible function to call.)
Is there a reason for such behaviour in the standard? Thanks!







c++ inheritance overloading multiple-inheritance






share|improve this question









New contributor




6yry6e is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




6yry6e is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 5 hours ago









Boann

36.8k1288121




36.8k1288121






New contributor




6yry6e is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 9 hours ago









6yry6e6yry6e

634




634




New contributor




6yry6e is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





6yry6e is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






6yry6e is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.













  • stackoverflow.com/questions/5103543/…

    – Jesper Juhl
    9 hours ago



















  • stackoverflow.com/questions/5103543/…

    – Jesper Juhl
    9 hours ago

















stackoverflow.com/questions/5103543/…

– Jesper Juhl
9 hours ago





stackoverflow.com/questions/5103543/…

– Jesper Juhl
9 hours ago












2 Answers
2






active

oldest

votes


















14














Ambiguity occurs when compiler tries to figure out to what entity does the name get refer to, prior to overload resolution. It can be a name of function from class A or from class B. In order to build a list of overloads complier needs to select just one of the classes to pull functions from. In order to fix it you can bring that name from both of the base classes into derived class (and make them public):



class C : public A, public B { public: using A::get; public: using B::get; };





share|improve this answer





















  • 2





    An annoying C++ niggle!

    – Lightness Races in Orbit
    9 hours ago











  • thanks a lot! c++ in his best... :)

    – 6yry6e
    9 hours ago






  • 8





    An important C++ protection: if adding a function to a base class changed the overload set your code could quietly break; with this rule it breaks noisily.

    – Pete Becker
    8 hours ago



















11














The problem is that you don't actually have one unified overload-set, in which the mutable variant would be unambiguously best, but two distinct overload-sets, in A and B, and the compiler will not automatically merge them.



Put



using A::get;
using B::get;


in C to merge the overload-sets and thus resolve the 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',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });






    6yry6e is a new contributor. Be nice, and check out our Code of Conduct.










    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54258524%2fwhy-is-inheritance-of-a-const-non-const-function-overload-ambiguous%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    14














    Ambiguity occurs when compiler tries to figure out to what entity does the name get refer to, prior to overload resolution. It can be a name of function from class A or from class B. In order to build a list of overloads complier needs to select just one of the classes to pull functions from. In order to fix it you can bring that name from both of the base classes into derived class (and make them public):



    class C : public A, public B { public: using A::get; public: using B::get; };





    share|improve this answer





















    • 2





      An annoying C++ niggle!

      – Lightness Races in Orbit
      9 hours ago











    • thanks a lot! c++ in his best... :)

      – 6yry6e
      9 hours ago






    • 8





      An important C++ protection: if adding a function to a base class changed the overload set your code could quietly break; with this rule it breaks noisily.

      – Pete Becker
      8 hours ago
















    14














    Ambiguity occurs when compiler tries to figure out to what entity does the name get refer to, prior to overload resolution. It can be a name of function from class A or from class B. In order to build a list of overloads complier needs to select just one of the classes to pull functions from. In order to fix it you can bring that name from both of the base classes into derived class (and make them public):



    class C : public A, public B { public: using A::get; public: using B::get; };





    share|improve this answer





















    • 2





      An annoying C++ niggle!

      – Lightness Races in Orbit
      9 hours ago











    • thanks a lot! c++ in his best... :)

      – 6yry6e
      9 hours ago






    • 8





      An important C++ protection: if adding a function to a base class changed the overload set your code could quietly break; with this rule it breaks noisily.

      – Pete Becker
      8 hours ago














    14












    14








    14







    Ambiguity occurs when compiler tries to figure out to what entity does the name get refer to, prior to overload resolution. It can be a name of function from class A or from class B. In order to build a list of overloads complier needs to select just one of the classes to pull functions from. In order to fix it you can bring that name from both of the base classes into derived class (and make them public):



    class C : public A, public B { public: using A::get; public: using B::get; };





    share|improve this answer















    Ambiguity occurs when compiler tries to figure out to what entity does the name get refer to, prior to overload resolution. It can be a name of function from class A or from class B. In order to build a list of overloads complier needs to select just one of the classes to pull functions from. In order to fix it you can bring that name from both of the base classes into derived class (and make them public):



    class C : public A, public B { public: using A::get; public: using B::get; };






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 9 hours ago

























    answered 9 hours ago









    VTTVTT

    24.4k42446




    24.4k42446








    • 2





      An annoying C++ niggle!

      – Lightness Races in Orbit
      9 hours ago











    • thanks a lot! c++ in his best... :)

      – 6yry6e
      9 hours ago






    • 8





      An important C++ protection: if adding a function to a base class changed the overload set your code could quietly break; with this rule it breaks noisily.

      – Pete Becker
      8 hours ago














    • 2





      An annoying C++ niggle!

      – Lightness Races in Orbit
      9 hours ago











    • thanks a lot! c++ in his best... :)

      – 6yry6e
      9 hours ago






    • 8





      An important C++ protection: if adding a function to a base class changed the overload set your code could quietly break; with this rule it breaks noisily.

      – Pete Becker
      8 hours ago








    2




    2





    An annoying C++ niggle!

    – Lightness Races in Orbit
    9 hours ago





    An annoying C++ niggle!

    – Lightness Races in Orbit
    9 hours ago













    thanks a lot! c++ in his best... :)

    – 6yry6e
    9 hours ago





    thanks a lot! c++ in his best... :)

    – 6yry6e
    9 hours ago




    8




    8





    An important C++ protection: if adding a function to a base class changed the overload set your code could quietly break; with this rule it breaks noisily.

    – Pete Becker
    8 hours ago





    An important C++ protection: if adding a function to a base class changed the overload set your code could quietly break; with this rule it breaks noisily.

    – Pete Becker
    8 hours ago













    11














    The problem is that you don't actually have one unified overload-set, in which the mutable variant would be unambiguously best, but two distinct overload-sets, in A and B, and the compiler will not automatically merge them.



    Put



    using A::get;
    using B::get;


    in C to merge the overload-sets and thus resolve the ambiguity.






    share|improve this answer




























      11














      The problem is that you don't actually have one unified overload-set, in which the mutable variant would be unambiguously best, but two distinct overload-sets, in A and B, and the compiler will not automatically merge them.



      Put



      using A::get;
      using B::get;


      in C to merge the overload-sets and thus resolve the ambiguity.






      share|improve this answer


























        11












        11








        11







        The problem is that you don't actually have one unified overload-set, in which the mutable variant would be unambiguously best, but two distinct overload-sets, in A and B, and the compiler will not automatically merge them.



        Put



        using A::get;
        using B::get;


        in C to merge the overload-sets and thus resolve the ambiguity.






        share|improve this answer













        The problem is that you don't actually have one unified overload-set, in which the mutable variant would be unambiguously best, but two distinct overload-sets, in A and B, and the compiler will not automatically merge them.



        Put



        using A::get;
        using B::get;


        in C to merge the overload-sets and thus resolve the ambiguity.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 9 hours ago









        DeduplicatorDeduplicator

        34.3k64888




        34.3k64888






















            6yry6e is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded


















            6yry6e is a new contributor. Be nice, and check out our Code of Conduct.













            6yry6e is a new contributor. Be nice, and check out our Code of Conduct.












            6yry6e is a new contributor. Be nice, and check out our Code of Conduct.
















            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54258524%2fwhy-is-inheritance-of-a-const-non-const-function-overload-ambiguous%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Terni

            A new problem with tex4ht and tikz

            Sun Ra