Search code examples
c++stringc++11unordered-set

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?


Solution

  • 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.