-2

Consider a function prototype:

void foo(const std::string& str);

If I call it with a const char* like this:

const char buffer[] = "Hello World!";
foo(buffer);

will it create a deep copy of the data? Or will it be a shallow copy?

Kaiyakha
  • 1,463
  • 1
  • 6
  • 19
  • it should not work. – apple apple Aug 13 '22 at 15:56
  • You can't pass a `char*` as argument to a function whose parameter is `string&`. This is explained in any beginner level [C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – Jason Aug 13 '22 at 15:56
  • It works with `const` with no warnings (c++14) – Kaiyakha Aug 13 '22 at 15:58
  • 1
    @Kaiyakha It will work with `const string&` because a const lvalue ref can bind to a tempoarary `string` created using the `char*`. – Jason Aug 13 '22 at 15:58
  • @JasonLiam will the temporary string have `char*` data as a deep copy? – Kaiyakha Aug 13 '22 at 16:00
  • @Kaiyakha The constructor `basic_string( const CharT* s, const Allocator& alloc = Allocator() );` can be used to create the temporary. – Jason Aug 13 '22 at 16:03
  • If you care of copy, use `std::string_view`. It should always be used if `const char*` argument is expected. – 273K Aug 13 '22 at 16:03
  • Dupe: [convert a char* to std::string](https://stackoverflow.com/a/1195690/12002570) – Jason Aug 13 '22 at 17:05

3 Answers3

1

will it create a deep copy of the data? Or will it be a shallow copy?

It will construct a temporary std::string object that deep copies the characters from the char[] into the std::string.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

Copy or not isn't really meaningful here.

A temporary std::string is constructed and passed to the function (as const reference).

(as a result the buffer is copied to the std::string internal buffer.)


you can also pass a std::string_view, then there would be no copy.

void foo(const std::string_view& str);
apple apple
  • 10,292
  • 2
  • 16
  • 36
0

will it create a copy of the data?

The char* that you're passing can be used to create a temporary std::string using the constructor:

basic_string( const CharT* s,
              const Allocator& alloc = Allocator() );

but the value category of that object will be rvalue which cannot bind to an non-const lvalue reference. This means, the given example will not work because a non-const lvalue reference cannot bind to an rvalue.

To solve this, you can add a low-level const in the parameter of the function like :

//-------vvvvv--------------------->low level const added
void foo(const std::string& str);

This works because a const lvalue reference can bind to an rvalue.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • I stood corrected, I added `const` – Kaiyakha Aug 13 '22 at 16:02
  • @Kaiyakha See my updated answer where a low-level const is added. Also, you should not change your question by taking suggestions given in the answers. That makes the answers pointless. – Jason Aug 13 '22 at 16:06
  • I guess I should've been more precise when posting this question. I meant to ask whether `const std::string&` creates a _deep_ or a _shallow_ copy when it receives `const char*` as an argument. – Kaiyakha Aug 13 '22 at 16:53
  • @Kaiyakha It will just create a copy using the passed `const char*` till the null `'\0'` is found. See [this](https://stackoverflow.com/a/1195690/12002570) where it says: *"deep copies the character list at `s`"* – Jason Aug 13 '22 at 17:02
  • 1
    @Kaiyakha you should not make changes to your question that invalidate a reasonable answer. – Mark Ransom Aug 14 '22 at 03:13