矢量vs字符串

时间:2010-12-29 19:08:05

标签: c++ string vector

C ++ std :: vector和std :: basic_string之间的根本区别是什么?

7 个答案:

答案 0 :(得分:19)

  • basic_string不调用其元素的构造函数和析构函数。矢量呢。

  • 交换basic_string使迭代器无效(启用小字符串优化),交换向量不会。

  • 在C ++ 03中不能连续分配basic_string内存。矢量总是连续的。在C ++ 0x [string.require]:

    中删除了这种差异
      

    basic_string对象中的类char对象应连续存储

  • basic_string具有字符串操作的接口。矢量没有。

  • basic_string可以在写策略上使用copy(在C ++ 11之前)。矢量不能。

非信徒的相关引言:

[basic.string]:

  

类模板basic_string符合序列容器(23.2.3)的要求   可逆容器(23.2),以及可识别分配器的容器(表99),但basic_string除外   不使用allocator_traits :: construct和allocator_-构造或销毁其元素   traits :: destroy和basic_string的swap()使迭代器无效。支持的迭代器   by basic_string是随机访问迭代器(24.2.7)。

答案 1 :(得分:12)

basic_string提供编译器和标准库实现,对vector的一些自由:

  1. “小字符串优化”对字符串有效,允许实现在字符串短时在字符串对象中存储实际字符串,而不是指向字符串的指针。有点像:

    class string
    {
        size_t length;
        union
        {
            char * usedWhenStringIsLong;
            char usedWhenStringIsShort[sizeof(char*)];
        };
    };
    
  2. 在C ++ 03中,底层数组不需要是连续的。根据现行标准,在“绳索”等方面实施basic_string是可能的。 (虽然没有人这样做,因为这会使成员std::basic_string::c_str()std::basic_string::data()实施成本太高。)
    C ++ 11现在禁止这种行为。

  3. 在C ++ 03中,basic_string允许编译器/库供应商对数据使用copy-on-write(可以保存副本),{{1}不允许这样做}。在实践中,这曾经是更常见的,但现在不太常见,因为它对多线程有影响。无论哪种方式,您的代码都不能依赖于std::vector是否使用COW实现 C ++ 11现在再次禁止这种行为。

  4. std::basic_string也有一些辅助方法,但大多数都很简单,当然可以在basic_string之上轻松实现。

答案 2 :(得分:6)

关键区别在于std::vector无法将std::basic_string数据保存在连续内存中。结果:

std::vector<char> v( 'a', 3 );
char* x = &v[0]; // valid

std::basic_string<char> s( "aaa" );
char* x2 = &s[0];     // doesn't point to continuous buffer
//For example, the behavior of 
std::cout << *(x2+1);
//is undefined.
const char* x3 = s.c_str(); // valid

On practice this difference is not so important.

答案 3 :(得分:0)

向量是模拟数组的数据结构。它内部深处实际上是一个(动态)数组。

basic_string类表示一个字符序列。它包含Sequence的所有常用操作,此外,它还包含标准字符串操作,如搜索和连接。

您可以使用向量来保留您想要的任何数据类型std::vector<int> or <float> or even std::vector< std::vector<T> >,但basic_string只能用于表示“文本”。

答案 4 :(得分:0)

basic_string提供了许多特定于字符串的比较选项。你是正确的,因为底层的内存管理接口非常相似,但字符串包含许多额外的成员,比如c_str(),这对于一个向量没有意义。

答案 5 :(得分:0)

std::stringstd::vector之间的一个区别是,程序可以从以null结尾的字符串构造一个字符串,而使用矢量则不能。

std::string a = "hello";          // okay
std::vector<char> b = "goodbye";  // compiler error

这通常使字符串更易于使用。

答案 6 :(得分:0)

TLDR:string被优化为仅包含字符基元,vector可以包含基元对象

vectorstring之间的一个显着差异是vector可以正确包含对象,string仅适用于基元。所以vector提供的这些方法对于使用基元的string来说是无用的:

  1. vector::emplace
  2. vector::emplace_back
  3. vector::~vector
  4. 即使扩展string也不允许它正确处理对象,因为它缺少析构函数。这不应该被视为一个缺点,它允许vector中的string进行重大优化:

    1. 执行short string optimization,可能会避免堆分配,littleno increased storage overhead
    2. 使用char_traits模板参数之一string来定义应如何对包含的基元实施操作(仅包含charwchar_t,{已实施{1}}和char16_thttp://en.cppreference.com/w/cpp/string/char_traits
    3. 特别相关的是char_traits::copychar_traits::movechar_traits::assign,显然意味着将使用直接赋值,而不是构造或破坏,这对于原语来说更可取。所有这些专业化都有char32_t的额外缺点:

      1. 仅使用stringcharwchar_tchar16_t基元类型。显然,大小不超过32位的基元,可以使用等效大小的char32_thttps://stackoverflow.com/a/35555016/2642059,但对于诸如char_type之类的基元来说,long long的新特性{ {1}}需要编写,专门设计char_traits::eofchar_traits::not_eof而不仅仅使用char_traits的想法似乎不是最好的时间用途。
      2. 由于字符串优化较短,所有使vector<long long>迭代器无效的操作都会使迭代器失效,但string::swapstring::operator= <vector迭代器会使string迭代器失效。 / LI>

        vectorstring的接口的其他差异:

        1. 没有可变的string::dataWhy Doesn't std::string.data() provide a mutable char*?
        2. string提供了处理vector中不可用字词的功能:string::c_strstring::lengthstring::appendstring::operator+=,{{3} },string::comparestring::replacestring::substrstring::copystring::findstring::rfindstring::find_first_ofstring::find_first_not_ofstring::flind_last_ofstring::find_last_not_ofstring::operator+string::operator>>string::operator<<string::stoistring::stolstring::stoll,{{ 3}},string::stoulstring::stoullstring::stofstring::stodstring::stold
        3. 最后,到处vector接受另一个vector的参数,string接受string 一个char*
        4. 请注意,这个答案是针对C ++ 11编写的,因此需要连续分配string