来自 std::unordered_set<char> 的有效构造 std::string

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

我有 unordered_set 个字符

std::unordered_set<char> u_setAlphabet;

然后我想从std::string集合中获取一个内容。我的实现现在看起来像这样:

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

这是解决这个任务的好方法吗?将 signle 字符添加到字符串似乎不是大型 u_setAlphabet(多个重新分配?)的最佳选择。还有其他方法吗?

std::stringa constructor 为:

auto s = std::string(begin(u_setAlphabet), end(u_setAlphabet));

最好使用接受迭代器的构造函数。例如

std::string getAlphabet() {
    return { u_setAlphabet.begin(), u_setAlphabet.end() };
}

最简单、最易读和最有效的答案是:

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

实现可以选择检测范围的长度up-front并且只分配一次;当给定前向迭代器范围时,libc++ 和 libstdc++ 都会这样做。

string class 也为您提供 reserve,就像 vector 一样,管理容量:

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

它还提供了assignappendinsert成员函数,但由于它们提供了强大的异常保证,它们可能必须在销毁旧缓冲区之前分配一个新缓冲区(感谢 @T.C. 指出了这个关键细节!)。如果现有容量足够,libc++ 实现不会重新分配,而 GCC5 的 libstdc++ 实现无条件重新分配。

return std::string(u_setAlphabet.begin(), u_setAlphabet.end());return { u_setAlphabet.begin(), u_setAlphabet.end(); 在 C++11 中是一样的。我更喜欢@VladfromMoscow 解决方案,因为我们不需要对临时对象的返回类型做出任何假设。