It seems obvious to consider a string to be a vector of characters. Why then does string have its own special implementation, which seems quite different from that of the vector class?
Just to illustrate the point, here are some snippets from both classes to show that the work needed is rather similar, e.g. both using an allocator to manage memory. Also having traits could be useful for vectors as well.
The following snipped from the implementation of std::string looks like it would fit into the more general implementation of std::vector if we would allow a vector to have type-traits.
139 template <class _charT, class _Traits , class _Allocator > |
140 class _RWSTDExportTemplate basic_string |
141 { |
142 public:
....
333 size_type size () const { return length(); } |
334 inline size_type length () const; |
335 size_type max_size () const |
336 { |
337 return npos - sizeof(__rep_type)-2; |
338 } |
339 inline void resize (size_type, _charT); |
340 void resize (size_type n) |
341 { |
342 resize(n,__eos()); |
343 } |
344 inline size_type capacity () const; |
345 inline void reserve (size_type=0); |
346 void clear () { erase(); } |
347 bool empty () const { return length() == 0; }
And this is from vector:
75 template <class _Tt, class _Allocator _RWSTD_COMPLEX_DEFAULT(allocator<_Tt>) > |
76 class vector |
77 { |
78
86 public: |
87 // |
88 // Types. |
89 // |
90 typedef _Tt value_type; |
91 typedef _Allocator allocator_type; |
92
383 // |
384 // Capacity.
385 //
386 size_type size () const { return size_type(end() - begin()); }
387 size_type max_size () const { return __value_alloc_type(__end_of_storage).max_size(); }
388 void resize (size_type new_size);
389 void resize (size_type new_size, _Tt value);
390
391 size_type capacity () const { return size_type(__end_of_storage.data() - begin()); }
392 bool empty () const { return begin() == end(); }
393 void reserve (size_type n)
394 {
395 _RWSTD_THROW(n > max_size(), length_error,
396 __RWSTD::except_msg_string(__RWSTD::__rwse_InvalidSizeParam,
397 "vector::reserve(size_t)",n,max_size()).msgstr());
398
399 if (capacity() < n)
400 {
401 __value_alloc_type va(__end_of_storage);
402 iterator tmp = va.allocate(n,__start);
403#ifndef _RWSTD_NO_EXCEPTIONS
404 try {
405 uninitialized_copy(begin(), end(), tmp);
406 } catch(...) {
407 __value_alloc_type(__end_of_storage).deallocate(tmp,n);
408 throw;
409 }
410#else
std::string offers a very different and much expanded interface compared to std::vector<> . While the latter is just a boring old sequence of elements, the former is actually designed to represent a string and therefore offers an assortment of string-related convenience functions.
There is no functionality difference between string and std::string because they're the same type.
std::string class in C++ C++ has in its definition a way to represent a sequence of characters as an object of the class. This class is called std:: string. String class stores the characters as a sequence of bytes with the functionality of allowing access to the single-byte character.
A std::string's allocation is not guaranteed to be contiguous under the C++98/03 standard, but C++11 forces it to be. In practice, neither I nor Herb Sutter know of an implementation that does not use contiguous storage.
Take for example this snippet:
string s = "abc";
There is no container that has a similar kind of initialisation syntax where it receives a pointer to the first element and scans the sequence for the special terminator element. Using a std::vector
would be cumbersome at least. Since texts are common in computing, having a convenient text container type is simply a necessity and std::vector
just doesn't fit.
That said, I could imagine std::string
inheriting std::vector<char>
privately or aggregating it, but that's a whole different issue than being a specialization of it. It also can't be a specialization, because what if you want a vector<char>
that does not behave like a string? You would then have the same fubar as with vector<bool>
today.
A std::string
has behavior that is not compatible with std::vector
, in particular the appearance of a zero-value at the end.
C++11 §21.4.5/2 about operator[]
, in [string.access]:
” Returns:
*(begin() + pos)
ifpos < size()
, otherwise a reference to an object of typeT
with valuecharT()
; the referenced value shall not be modified.
Another big difference is that std::string
supports the small buffer optimization, while that optimization possibility is not available for std::vector
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With