Why does the compiler prefer f(const void*) to f(const std::string &)?











up vote
39
down vote

favorite
7












Consider the following piece of code:



#include <iostream>
#include <string>

// void f(const char *) { std::cout << "const char *"; } // <-- comment on purpose
void f(const std::string &) { std::cout << "const std::string &"; }
void f(const void *) { std::cout << "const void *"; }

int main()
{
f("hello");
std::cout << std::endl;
}


I compiled this program using g++ (Ubuntu 6.5.0-1ubuntu1~16.04) 6.5.0 20181026:



$ g++ -std=c++11 strings_1.cpp -Wall
$ ./a.out

const void *


Note that the comment is there on purpose to test, otherwise the compiler uses f(const char *).



So, why does the compiler pick f(const void*) over f(const std::string &)?










share|improve this question









New contributor




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
















  • 4




    Here's the relevant part of the standard: eel.is/c++draft/over.ics.rank#2.1
    – geza
    Nov 17 at 18:53










  • @geza awesome. I was looking for it, thanks.
    – omar
    Nov 17 at 18:56










  • The overloading resolution rule here is simple and unchanged in the many C++ versions.
    – curiousguy
    Nov 17 at 19:01






  • 4




    Well, a string literal is not an std::string, it's a static array of chars, which decays to a pointer to its first character. This behavior is inherited from C which never had something like std::string, but ample amounts of code handling strings nonetheless.
    – cmaster
    Nov 17 at 21:49






  • 1




    If you specifically want a std::string literal you can achieve that by adding a s behind the literal. This is a user-defined literal which is available since C++14. en.cppreference.com/w/cpp/string/basic_string/operator%22%22s
    – henje
    Nov 18 at 10:56















up vote
39
down vote

favorite
7












Consider the following piece of code:



#include <iostream>
#include <string>

// void f(const char *) { std::cout << "const char *"; } // <-- comment on purpose
void f(const std::string &) { std::cout << "const std::string &"; }
void f(const void *) { std::cout << "const void *"; }

int main()
{
f("hello");
std::cout << std::endl;
}


I compiled this program using g++ (Ubuntu 6.5.0-1ubuntu1~16.04) 6.5.0 20181026:



$ g++ -std=c++11 strings_1.cpp -Wall
$ ./a.out

const void *


Note that the comment is there on purpose to test, otherwise the compiler uses f(const char *).



So, why does the compiler pick f(const void*) over f(const std::string &)?










share|improve this question









New contributor




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
















  • 4




    Here's the relevant part of the standard: eel.is/c++draft/over.ics.rank#2.1
    – geza
    Nov 17 at 18:53










  • @geza awesome. I was looking for it, thanks.
    – omar
    Nov 17 at 18:56










  • The overloading resolution rule here is simple and unchanged in the many C++ versions.
    – curiousguy
    Nov 17 at 19:01






  • 4




    Well, a string literal is not an std::string, it's a static array of chars, which decays to a pointer to its first character. This behavior is inherited from C which never had something like std::string, but ample amounts of code handling strings nonetheless.
    – cmaster
    Nov 17 at 21:49






  • 1




    If you specifically want a std::string literal you can achieve that by adding a s behind the literal. This is a user-defined literal which is available since C++14. en.cppreference.com/w/cpp/string/basic_string/operator%22%22s
    – henje
    Nov 18 at 10:56













up vote
39
down vote

favorite
7









up vote
39
down vote

favorite
7






7





Consider the following piece of code:



#include <iostream>
#include <string>

// void f(const char *) { std::cout << "const char *"; } // <-- comment on purpose
void f(const std::string &) { std::cout << "const std::string &"; }
void f(const void *) { std::cout << "const void *"; }

int main()
{
f("hello");
std::cout << std::endl;
}


I compiled this program using g++ (Ubuntu 6.5.0-1ubuntu1~16.04) 6.5.0 20181026:



$ g++ -std=c++11 strings_1.cpp -Wall
$ ./a.out

const void *


Note that the comment is there on purpose to test, otherwise the compiler uses f(const char *).



So, why does the compiler pick f(const void*) over f(const std::string &)?










share|improve this question









New contributor




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











Consider the following piece of code:



#include <iostream>
#include <string>

// void f(const char *) { std::cout << "const char *"; } // <-- comment on purpose
void f(const std::string &) { std::cout << "const std::string &"; }
void f(const void *) { std::cout << "const void *"; }

int main()
{
f("hello");
std::cout << std::endl;
}


I compiled this program using g++ (Ubuntu 6.5.0-1ubuntu1~16.04) 6.5.0 20181026:



$ g++ -std=c++11 strings_1.cpp -Wall
$ ./a.out

const void *


Note that the comment is there on purpose to test, otherwise the compiler uses f(const char *).



So, why does the compiler pick f(const void*) over f(const std::string &)?







c++ stdstring string-literals function-overloading overload-resolution






share|improve this question









New contributor




omar 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




omar 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 Nov 17 at 19:00









curiousguy

4,47722940




4,47722940






New contributor




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









asked Nov 17 at 18:27









omar

25919




25919




New contributor




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





New contributor





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






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








  • 4




    Here's the relevant part of the standard: eel.is/c++draft/over.ics.rank#2.1
    – geza
    Nov 17 at 18:53










  • @geza awesome. I was looking for it, thanks.
    – omar
    Nov 17 at 18:56










  • The overloading resolution rule here is simple and unchanged in the many C++ versions.
    – curiousguy
    Nov 17 at 19:01






  • 4




    Well, a string literal is not an std::string, it's a static array of chars, which decays to a pointer to its first character. This behavior is inherited from C which never had something like std::string, but ample amounts of code handling strings nonetheless.
    – cmaster
    Nov 17 at 21:49






  • 1




    If you specifically want a std::string literal you can achieve that by adding a s behind the literal. This is a user-defined literal which is available since C++14. en.cppreference.com/w/cpp/string/basic_string/operator%22%22s
    – henje
    Nov 18 at 10:56














  • 4




    Here's the relevant part of the standard: eel.is/c++draft/over.ics.rank#2.1
    – geza
    Nov 17 at 18:53










  • @geza awesome. I was looking for it, thanks.
    – omar
    Nov 17 at 18:56










  • The overloading resolution rule here is simple and unchanged in the many C++ versions.
    – curiousguy
    Nov 17 at 19:01






  • 4




    Well, a string literal is not an std::string, it's a static array of chars, which decays to a pointer to its first character. This behavior is inherited from C which never had something like std::string, but ample amounts of code handling strings nonetheless.
    – cmaster
    Nov 17 at 21:49






  • 1




    If you specifically want a std::string literal you can achieve that by adding a s behind the literal. This is a user-defined literal which is available since C++14. en.cppreference.com/w/cpp/string/basic_string/operator%22%22s
    – henje
    Nov 18 at 10:56








4




4




Here's the relevant part of the standard: eel.is/c++draft/over.ics.rank#2.1
– geza
Nov 17 at 18:53




Here's the relevant part of the standard: eel.is/c++draft/over.ics.rank#2.1
– geza
Nov 17 at 18:53












@geza awesome. I was looking for it, thanks.
– omar
Nov 17 at 18:56




@geza awesome. I was looking for it, thanks.
– omar
Nov 17 at 18:56












The overloading resolution rule here is simple and unchanged in the many C++ versions.
– curiousguy
Nov 17 at 19:01




The overloading resolution rule here is simple and unchanged in the many C++ versions.
– curiousguy
Nov 17 at 19:01




4




4




Well, a string literal is not an std::string, it's a static array of chars, which decays to a pointer to its first character. This behavior is inherited from C which never had something like std::string, but ample amounts of code handling strings nonetheless.
– cmaster
Nov 17 at 21:49




Well, a string literal is not an std::string, it's a static array of chars, which decays to a pointer to its first character. This behavior is inherited from C which never had something like std::string, but ample amounts of code handling strings nonetheless.
– cmaster
Nov 17 at 21:49




1




1




If you specifically want a std::string literal you can achieve that by adding a s behind the literal. This is a user-defined literal which is available since C++14. en.cppreference.com/w/cpp/string/basic_string/operator%22%22s
– henje
Nov 18 at 10:56




If you specifically want a std::string literal you can achieve that by adding a s behind the literal. This is a user-defined literal which is available since C++14. en.cppreference.com/w/cpp/string/basic_string/operator%22%22s
– henje
Nov 18 at 10:56












1 Answer
1






active

oldest

votes

















up vote
48
down vote



accepted










Converting to a std::string requires a "user defined conversion".



Converting to void const* does not.



User defined conversions are ordered behind built in ones.






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


    }
    });






    omar 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%2f53354226%2fwhy-does-the-compiler-prefer-fconst-void-to-fconst-stdstring%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    48
    down vote



    accepted










    Converting to a std::string requires a "user defined conversion".



    Converting to void const* does not.



    User defined conversions are ordered behind built in ones.






    share|improve this answer

























      up vote
      48
      down vote



      accepted










      Converting to a std::string requires a "user defined conversion".



      Converting to void const* does not.



      User defined conversions are ordered behind built in ones.






      share|improve this answer























        up vote
        48
        down vote



        accepted







        up vote
        48
        down vote



        accepted






        Converting to a std::string requires a "user defined conversion".



        Converting to void const* does not.



        User defined conversions are ordered behind built in ones.






        share|improve this answer












        Converting to a std::string requires a "user defined conversion".



        Converting to void const* does not.



        User defined conversions are ordered behind built in ones.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 17 at 18:40









        Yakk - Adam Nevraumont

        178k19185363




        178k19185363






















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










             

            draft saved


            draft discarded


















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













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












            omar 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%2f53354226%2fwhy-does-the-compiler-prefer-fconst-void-to-fconst-stdstring%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

            AnyDesk - Fatal Program Failure

            How to calibrate 16:9 built-in touch-screen to a 4:3 resolution?

            QoS: MAC-Priority for clients behind a repeater