Stl - Is a string a vector?

In a quiz, I came across the question " Is a string a vector? If yes, in what way? If no, why not? " Both have random access to the content. But the string has some methods that dosn`t.It vector can also have a reference counter. Thus, it is obvious that the string is not exactly a vector (typedef string vector) Are implementations known in which class string : public vector <char> ? If not, what is the reason not to implement it?

+6
source share
4 answers

From a purely philosophical point of view: yes, a string is a type of vector. This is a continuous memory block in which characters are stored (a vector is a continuous memory block in which objects of arbitrary types are stored). So, from this point of view, a string is a special kind of vector.

From the point of view of design and implementation, std::string and std::vector they have the same interface elements (for example, adjacent memory blocks, operator[] ), but std::string does not follow from std::vector (reverse note: you should not be publicly deduced from standard containers, since they are not intended for classes, for example, they do not have virtual destructors), and they cannot be directly converted to each other. That is, the following will not compile:

 std::string s = "abc"; std::vector<char> v = s; // ERROR! 

However, since both of them support an iterator, you can convert the string to a vector:

 std::string s = "abc"; std::vector<char> v(s.begin(), s.end()); // note that the vector will NOT include the '\0' character 

std::string will no longer have a reference counter (as in C ++ 11) as a copy-to-write function, which was used in many implementations of the C ++ 11 standard.

From a memory point of view, an instance of std::string will be very similar to std::vector<char> (for example, both of them will have a pointer to their location in memory, size, capacity), but the functionality of the two classes is different.

+7
source

std::string has a non-trivial part of this interface that is common with std::vector (and other standard containers), but this is definitely a different matter for a different purpose.

It can also be implemented in different ways, because it allows things like optimizing small lines or copying to a record (not legal since 2011). (Although it is certainly possible for them very similar implementations).

Both of them support random access iterators, so they can be used in a similar way with standard algorithms. I think std::string cannot be classified as a sequence container.

It is not possible to implement many member functions of std::string directly, inheriting from std::vector , because it hides the fact that it also stores a NUL terminator. Therefore, when std::string::size returns 3 , std::vector::size will return 4 , for example. The same goes for end and a few others.

+11
source

No, std::string ( std::basic_string<char> ), you can think of it as a sequence container that contains char , since it shares many functions with other containers, but is not implemented using std::vector .

+3
source

The main reason it cannot (or at least should not) be implemented using shared inheritance is that implicit conversion from string to vector should not be allowed. For example, if I write code like:

 int f(std::vector<char> const &s); // ... std::string s; f(s); 

Compilation should fail (there is no other f overload that accepts string ).

If you really wanted to, you could (probably) make a legal implementation of std::string using private inheritance from std::vector . This may not be as effective as possible, but at least because of this I cannot think of a requirement that he would clearly violate. The loss of efficiency will be that std::vector requires a bit more general - it should support the creation of instances by types that can throw exceptions, while std::string is only intended to create instances by types that are not an exception.

+3
source

Source: https://habr.com/ru/post/957199/


All Articles