Elegantly concantenating std::string_view and string literal into a std::string
Assume I have the following function:
std::string greeting(const std::string_view name){
return std::string(name) + " we wish you a very nice day and week and month and year";
}
It works fine, but I want to avoid more than 1 memory allocation, assuming name is too long to fit into SSO buffer. So I came up with this:
std::string greeting_efficient(const std::string_view name){
constexpr std::string_view suffix = " we wish you a very nice day and week and month and year";
std::string result;
result.reserve(name.size()+suffix.size());
result+=name;
result+=suffix;
return result;
}
AFAIK it works but it is quite ugly, is there a easier way to do this?
I am fine with using C++20/23 if solution needs it.
2 answers
-
answered 2022-05-04 10:47
WBuck
You could use
std::format
which is aC++20
feature. Or you could pull in the fmt library which is whatstd::format
is based off of if your compiler hasn't implementedstd::format
yet.#include <iostream> #include <format> #include <string> static std::string greeting(std::string_view name) { return std::format("{} have a very nice day", name); } int main() { std::cout << greeting("Bill") << '\n'; }
You could also use an
std::stringstream
as well, but I'm unsure how efficient it is.static std::string greeting(std::string_view name) { std::ostringstream os{}; os << name << " have a very nice day"; return os.str(); }
-
answered 2022-05-04 10:47
Ted Lyngmo
I'm not sure if it's more elegant or not, but this should assure that there's only one allocation:
- Initialize the
std::string
with the correct size instead of default constructing it and reserving space. Expected effects:- (+) It makes the one allocation directly at construction.
- (+) The string's internal size counter will not be changed in the rest of the process.
- (-) It initializes the memory with the character of your choice.
- Copy
name
directly into the string's memory. - Copy
suffix
directly into the string's memory.- Both copy operations needed should be using the fastest copying available. Two
memcpy
s ormemmove
s will likely be the result.
- Both copy operations needed should be using the fastest copying available. Two
#include <algorithm> std::string greeting(std::string_view name){ static constexpr std::string_view suffix = " we wish you a very nice day" " and week and month and year"; std::string rv(name.size() + suffix.size(), '\0'); // one allocation std::copy(suffix.begin(), suffix.end(), std::copy(name.begin(), name.end(), rv.begin())); return rv; }
- Initialize the
How many English words
do you know?
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
how many words do you know
Powered by Examplum