1

I have found this the code example while searching for code snippet to split(similar to PHP's explode) std::string to a vector of substrings using delimiter of ' '(a Space :). String example - "one two three".

std::vector<std::string> split(const std::string& s, char delimiter)
{
   std::vector<std::string> tokens;
   std::string token;
   std::istringstream tokenStream(s);
   while (std::getline(tokenStream, token, delimiter))
   {
      tokens.push_back(token);
   }
   return tokens;
}

My problem is with scope of variable 'tokens'. Will it be an error to use such a split function because the scope of local variable ends once the function returns. I have an idea how to correct the problem, i am just not sure in my c++ skill. I am curious in ways of doing it in standards up to C++0x for use of such: explode(string, delimiter).

6
  • 2
    tokens is being returned by value (thus creating a copy), so I'm unsure which scope problem you are referring to Commented Dec 14, 2019 at 0:34
  • my thought is that its contense will be lost once the execution reaches the end of function, it won't? Commented Dec 14, 2019 at 0:36
  • 2
    No, the function returns by value, so it will copy the contents of tokens (the compiler might optimize the copying, but the observable behavior will stay the same) Commented Dec 14, 2019 at 0:37
  • 2
    Try it out and measure it - it probably depends on how you use the function Commented Dec 14, 2019 at 0:41
  • 1
    Turn on the optimizer and use a compiler made in the last 15 years and you will almost certainly see copy elision kick in and eliminate the copying. Commented Dec 14, 2019 at 0:48

1 Answer 1

1

The tokens variable will indeed not survive the return of the function. But the return is by value, and the value returned survives in the calling context.

For the optimization, the best would be to let the compiler do its job and only fine tune if necessary. Here, the compiler may generate:

1) a copy elision, constructing the return value directly into its target. Example: auto r=split(s, ' ');
2) a move assignment if the target was already previously constructed. Example:
r=split(s, ' ');

Both cases avoid unnecessary copy of data. You can have a look at the Test class here for understanding.

Returning by reference would be UB, since the reference would refer to a variable that no longer exists. So returning by reference would mean to use a reference parameter to write directly in to the right target variable. But this will not outperform the copy elision. And it would probably only rarely outperform a move assignment. But in case of a doubt, you can try to make a benchmark.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.