I need to call a function, whose parameters are type string.
I thought std::string
is a good choice, because it provide a lot of interface.
But recently, I found there is a copy happened when i pass char *
to const std::string &
.
here is the code:
#include <iostream>
#include <string>
using namespace std;
void test_string(const std::string & s) {
printf("%p\n", s.data());
}
int main() {
char aa[] = "asd";
test_string(aa);
printf("%p\n", aa);
}
As the above code shows, I can pass std::string and char []
to my function test_string
.
And my arg type is const std::string &
, I thought it would be no copy happened.
But the output shows the address is different, I think the function construct a tempory variable string, which copy from my char []
one by one. which is not neccessary.
Is this a bad usage (pass char[]
to std::string
)? Is there any good advice to avoid copy?
aa
is a char
array, not a std::string
, and so a temporary std::string
object is constructer to be passed by reference (as s
) into test_string
.
When this temporary object is constructed a copy is made (a std::string
always owns the data).
If you change aa
to be a std::string
, no copy will be done and it will be passed by reference.
Alternativly change test_string
to accept a std::string_view
. A std::string_view
does not make a copy when it is constructed (it is just a non-owning view into an existing string and can be constructed from a char
array as well as from another std::string
).
As all view types (which ar lightweight), you should by default pass std::string_view
by value.
This article explains it in more details: Three reasons to pass std::string_view by value.