Why does the compiler prefer f(const void*) to f(const std::string &)?
up vote
40
down vote
favorite
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
|
show 2 more comments
up vote
40
down vote
favorite
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
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 anstd::string
, it's a static array ofchar
s, which decays to a pointer to its first character. This behavior is inherited from C which never had something likestd::string
, but ample amounts of code handling strings nonetheless.
– cmaster
Nov 17 at 21:49
1
If you specifically want astd::string
literal you can achieve that by adding as
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
|
show 2 more comments
up vote
40
down vote
favorite
up vote
40
down vote
favorite
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
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
c++ stdstring string-literals function-overloading overload-resolution
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 anstd::string
, it's a static array ofchar
s, which decays to a pointer to its first character. This behavior is inherited from C which never had something likestd::string
, but ample amounts of code handling strings nonetheless.
– cmaster
Nov 17 at 21:49
1
If you specifically want astd::string
literal you can achieve that by adding as
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
|
show 2 more comments
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 anstd::string
, it's a static array ofchar
s, which decays to a pointer to its first character. This behavior is inherited from C which never had something likestd::string
, but ample amounts of code handling strings nonetheless.
– cmaster
Nov 17 at 21:49
1
If you specifically want astd::string
literal you can achieve that by adding as
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 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
Nov 17 at 21:49
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
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
|
show 2 more comments
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.
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 17 at 18:40
Yakk - Adam Nevraumont
179k19187367
179k19187367
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 ofchar
s, which decays to a pointer to its first character. This behavior is inherited from C which never had something likestd::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 as
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