Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Effective construction std::string from std::unordered_set<char>

I have an unordered_set of chars

std::unordered_set<char> u_setAlphabet;

Then I want to get a content from the set as std::string. My implementation now looks like this:

std::string getAlphabet() {
    std::string strAlphabet;
    for (const char& character : u_setAlphabet)
        strAlphabet += character;
    return strAlphabet;
}

Is this a good way to solve this task? The additions of signle chars to string seems not to be optimal for large u_setAlphabet (multiple reallocs?). Is there any other method to it?

like image 909
saleph Avatar asked Dec 30 '15 11:12

saleph


2 Answers

The simplest, most readable and most efficient answer is:

return std:string(s.begin(), s.end());

The implementation may choose to detect the length of the range up-front and only allocate once; both libc++ and libstdc++ do this when given a forward iterator range.

The string class also offers you reserve, just like vector, to manage the capacity:

std::string result
result.reserve(s.size());
for (unsigned char c : s) result.push_back(c);   // or std::copy
return result;

It also offers assign, append and insert member functions, but since those offer the strong exception guarantee, they may have to allocate a new buffer before destroying the old one (thanks to @T.C. for pointing out this crucial detail!). The libc++ implementation does not reallocate if the existing capacity suffices, while GCC5's libstdc++ implementation reallocates unconditionally.

like image 116
Kerrek SB Avatar answered Sep 28 '22 05:09

Kerrek SB


std::string has a constructor for that:

auto s = std::string(begin(u_setAlphabet), end(u_setAlphabet));
like image 25
xtofl Avatar answered Sep 28 '22 06:09

xtofl