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 &)
?
A const void* means a pointer to some data that cannot be changed. In order to read it, yes, you have to cast it to concrete types such as char .
The data type const string& literally means “a reference to a string object whose contents will not be changed.” There are three ways to pass things around (into and out of functions) in C++: 1. Pass by value - a copy of the original object is created and passed.
If you don't have the choice, using const char* gives a guarantee to the user that you won't change his data especially if it was a string literal where modifying one is undefined behavior. Show activity on this post. By using const you're promising your user that you won't change the string being passed in.
const void is a type which you can form a pointer to. It's similar to a normal void pointer, but conversions work differently. For example, a const int* cannot be implicitly converted to a void* , but it can be implicitly converted to a const void* .
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With