17

My question is motivated by this answer on stackoverflow, https://stackoverflow.com/a/48082010/5360439. To quote,

Q: How you convert a std::string_view to a const char*?

A: Simply do a std::string(string_view_object).c_str() to get a guaranteed null-terminated temporary copy (and clean it up at the end of the line).

Unfortunately, it constructs a new string. I am wondering if it is OK to simply do,

static_cast<string>(string_view_object).c_str()

Now, my question is:

  1. Does this constructs a new string?

  2. Is it guaranteed to return a null-terminated char sequence?

I have a small piece of code for demonstration. It seems to work fine. (See wandbox results)

#include <string>
#include <iostream>
#include <string_view>
#include <cstring>

int main()
{
  std::string str{"0123456789"};
  std::string_view sv(str.c_str(), 5);

  std::cout << sv << std::endl;
  std::cout << static_cast<std::string>(sv) << std::endl;
  std::cout << strlen(static_cast<std::string>(sv).c_str()) << std::endl;
}
Community
  • 1
  • 1
JohnKoch
  • 833
  • 9
  • 25
  • 5
    Yes, that also creates a temporary `string` object. I don't know how you expect to get the contents placed next to a NUL character without having a copy. – Ben Voigt Jan 16 '19 at 06:27
  • 4
    `static_cast(o)` is pretty much the same as `T(o)`. – molbdnilo Jan 16 '19 at 06:28
  • 2
    Please don't add a verification that essentially answers your question after someone posted an answer. It invalidates that person's effort. If the question was answered to your satisfaction, accept that answer please. Or post another answer with your own solution. SO is a Q&A site. Questions belong at the question box, answers at the answer section. – StoryTeller - Unslander Monica Jan 16 '19 at 07:00
  • @StoryTeller Sorry, I wasn't meant to invalidate efforts from other people. I haven never answered my question before, so my first thought is to post my answer by editing the question. Thanks for explaining the rule to me. – JohnKoch Jan 16 '19 at 07:24
  • 1
    No worries. I know no ill will was present. Also don't be afraid to answer your own questions if you figured something useful out for yourself and think others may benefit. It's [highly encouraged](https://stackoverflow.com/help/self-answer) in fact :) – StoryTeller - Unslander Monica Jan 16 '19 at 07:26

2 Answers2

13

static_cast<std::string>(sv) is calling the std::string::string constructor that expects any type convertible to std::string_view (more details). Therefore, yes, it's still creating a brand new std::string object, which in turn guarantees a null-terminated char sequence.

Mário Feroldi
  • 2,935
  • 2
  • 21
  • 42
  • 1
    I'd phrase that as "yes and yes" (OP asked two questions). – Arne Vogel Jan 16 '19 at 10:30
  • 1
    A string is NOT null-terminated. It's the c_str() function that adds the null at the end. – Triskeldeian Jun 08 '20 at 08:47
  • The internal state of `std::string` may not hold a null-terminated string, but its interface provides one, i.e., `data()` and `c_str()` are both guaranteed to return a pointer to a null-terminated array of `char`. – Mário Feroldi Jun 10 '20 at 02:23
-3

A simple way to check if static_cast<std::string>(sv) constructs a new string is to verify if it's able to change original string.

#include <string>
#include <iostream>
#include <string_view>
#include <cstring>

int main()
{
  std::string str{"0123456789"};
  std::string_view sv = str;

  std::cout << sv << std::endl;
  static_cast<std::string>(sv)[0] = 'a';
  std::cout << static_cast<std::string>(sv) << std::endl;
} 

sv remains unchanged, so it does creates a new string.

See results on wandbox.

JohnKoch
  • 833
  • 9
  • 25
  • 3
    You have to be careful with that "try it and see" approach particularly when it comes to strings. For example `const char* s = "hello";` followed by a `const_cast` and an attempt to modify that string by array indexing *sometimes* works, but actually the behaviour is undefined. The best thing to do is to check the documentation. – Bathsheba Jan 16 '19 at 08:28