46

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 &)?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
omar
  • 629
  • 4
  • 13
  • 5
    Here's the relevant part of the standard: http://eel.is/c++draft/over.ics.rank#2.1 – geza Nov 17 '18 at 18:53
  • @geza awesome. I was looking for it, thanks. – omar Nov 17 '18 at 18:56
  • The overloading resolution rule here is simple and unchanged in the many C++ versions. – curiousguy Nov 17 '18 at 19:01
  • ```#include #include int main() { std::cout << typeid("foo").name() << " - " << typeid(string("foo")).name(); return 0; }``` – hanshenrik Nov 17 '18 at 21:44
  • 4
    Well, a string literal is **not an `std::string`**, it's a static array of `char`s, 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 - reinstate monica Nov 17 '18 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. https://en.cppreference.com/w/cpp/string/basic_string/operator%22%22s – henje Nov 18 '18 at 10:56
  • @geza Consider posting as an answer... – user202729 Nov 18 '18 at 13:09

1 Answers1

54

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.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524