2

I am working on the following code:

std::string myFunc(std::string_view stringView)
{
    size_t i = stringView.find_last_of("/\\");
    if (i != std::string::npos)
      return stringView.substr(i + 1);
    return stringView;
}

int main()
{
    std::string testString{"TestString"};
    std::string_view testView{testString};
    std::string test{testView};

    return 0;
}

where I am passing a string_view to the function myFunc(). The function returns a std::string since I've read that it's better to not return a string_view.

However, the compiler is giving the following two errors:

<source>: In function 'std::string myFunc(std::string_view)':
<source>:19:31: error: could not convert 'stringView.std::basic_string_view<char>::substr((i + 1), ((std::basic_string_view<char>::size_type)std::basic_string_view<char>::npos))' from 'std::basic_string_view<char>' to 'std::string' {aka 'std::__cxx11::basic_string<char>'}
   19 |       return stringView.substr(i + 1);
      |              ~~~~~~~~~~~~~~~~~^~~~~~~
      |                               |
      |                               std::basic_string_view<char>
<source>:20:12: error: could not convert 'stringView' from 'std::string_view' {aka 'std::basic_string_view<char>'} to 'std::string' {aka 'std::__cxx11::basic_string<char>'}
   20 |     return stringView;
      |            ^~~~~~~~~~
      |            |
      |            std::string_view {aka std::basic_string_view<char>}

What is the correct way to solve this if I want a std::string as returned type? See the link for the compiler error snapshot Thanks in advance

Creating a local string and initialize it with the string_view could be a solution (?)

compilation_error

wohlstad
  • 12,661
  • 10
  • 26
  • 39
CepBoy
  • 25
  • 5
  • Yes, creating a local string is exactly what you need to do, since evidently `std::string` doesn't have a constructor that takes a `std::string_view`. That seems like an oversight, but not much you can do about it. – Mark Ransom Aug 17 '23 at 12:40
  • 1
    *"since I've read that it's better to not return a `string_view`"* `std::string_view` has no ownership, so you have to be careful about lifetime when returning `std::string_view`, it seems correct for your code to return `std::string_view`. – Jarod42 Aug 17 '23 at 13:05

1 Answers1

4

There is no implicit conversion from std::string_view to std::string.
You can see more about it here:

Why is there no implicit conversion from std::string_view to std::string?

However, since C++17, there is an explicit std::string constructor (look at overload (10)) that accepts a std::string_view. You can use it to construct a std::string to return from your function:

std::string myFunc(std::string_view stringView)
{
    size_t i = stringView.find_last_of("/\\");
    if (i != std::string::npos)
        return std::string{ stringView.substr(i + 1) };
    return std::string{ stringView };
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
wohlstad
  • 12,661
  • 10
  • 26
  • 39
  • 1
    I'm glad you answered this. I did some research and discovered the comment I left on the question wasn't quite correct. – Mark Ransom Aug 17 '23 at 12:54