为什么std :: string没有保留构造函数?

时间:2015-09-23 11:52:28

标签: c++ string

std::string有几个constructors。我正在寻找一种避免重新分配的方法,我很惊讶有一个填充构造函数,但没有"保留"构造

 std::string (size_t n, char c);

但没有

 std::string (size_t n);

所以我必须在已经分配了默认值(在我的情况下是16个字节)之后调用reserve(),只是为了立即重新分配它?

为什么没有这样的构造函数在创建对象时直接保留空间,而不是必须手动执行?或者我错过了什么,有办法做到这一点?

使用fill构造函数是浪费时间,因为它会遍历内存只是为了被覆盖,并且还会导致错误的大小,因为s.length()报告N而不是0 }。

3 个答案:

答案 0 :(得分:3)

这都是猜测,但我会尝试。

如果您已经知道所需字符串的大小,则很可能是从其他地方复制数据,例如从另一个字符串。在这种情况下,您可以调用其中一个接受char *const std::string &的构造函数来立即复制数据。

另外,我不明白为什么在构造字符串后立即使用reserve是件坏事。虽然它是实现定义的,但我认为这对于这段代码是有意义的:

std::string str;
str.reserve(100);

为总共100个元素分配内存,而不是116(在"首先分配16,然后释放它们并再分配100个"),因此对不存在的预留构造函数没有性能影响

另外,如果你只想要一个没有默认分配的字符串,你可能会使用std::string str(0, ' ');使" 无效使用填充构造函数是浪费时间"点。

答案 1 :(得分:0)

保留构造函数的一种使用情况可能是将std :: string与静态/ thread_local存储一起用于高速缓存变量。

void function(){
   thread_local std::string str; // no reserving constructor defined
}

在这种情况下,您可以编写一个lambda函数,该函数构造std :: string并保留所需的内存量。

void function(){
    auto reserving_string_constr = [](std::size_t reserve_size){
        std::string str;
        str.reserve(reserve_size);
        return str;
    };
    thread_local std::string str(reserving_string_constr(128));
    /*...*/
}

答案 2 :(得分:-1)

你基本上可以对每个没有体现为构造函数的CacheItemPolicy方法提出同样的问题。

例如,为什么我们没有一个构造函数,它接受多个字符串并将它们逐个附加到新创建的字符串中?

为什么不重载保留内存的构造函数可能有很多原因。我认为在面向对象的setmind中,“保留内存字符串”的想法有点奇怪。字符串表示一系列字符,而不是它背后的内存 - 这是实现细节,而不是主要特征。当有人打开一个新的餐厅时,他是否认为“当这个餐厅最终开放时,在开放的那一刻,我会为所谓的100人团体预留100个座位,这个团体可能会或者可能不会来!”

但你的问题隐含地陈述了一些非常明确的东西:C ++中缺少适当的缓冲对象。你问保留构造函数,因为你想使用字符串作为缓冲区,但零初始化它们是非常昂贵的。保留内存不会让你写出超出字符串大小 因此,解决这个问题的方法是使用std::string,它不会对字符进行归零,但会为您提供所需的RAII样式。