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











up vote
40
down vote

favorite
8












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




















  • 5




    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
40
down vote

favorite
8












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




















  • 5




    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
40
down vote

favorite
8









up vote
40
down vote

favorite
8






8





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















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















share|improve this question













share|improve this question




share|improve this question








edited Nov 17 at 19:00









curiousguy

4,50422940




4,50422940










asked Nov 17 at 18:27









omar

26419




26419








  • 5




    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














  • 5




    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








5




5




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


    }
    });














    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
    52
    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
      52
      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
        52
        down vote



        accepted







        up vote
        52
        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

        179k19187367




        179k19187367






























            draft saved

            draft discarded




















































            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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%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

            QoS: MAC-Priority for clients behind a repeater

            Ивакино (Тотемский район)

            Can't locate Autom4te/ChannelDefs.pm in @INC (when it definitely is there)