Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interpret a std::string as a std::vector of char_type?

I have a template<typename T> function that takes a const vector<T>&. In said function, I have vectors cbegin(), cend(), size(), and operator[]. As far as I understand it, both string and vector use contiguous space, so I was wondering if I could reuse the function for both data types in an elegant manner.

Can a std::string be reinterpreted as a std::vector of (the appropriate) char_type? If so, what would the limitations be?

like image 979
Anzurio Avatar asked Oct 08 '15 21:10

Anzurio


People also ask

What is the difference between std::string and std::vector?

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.

How do you copy a string in vector?

std::string str = "hello"; std::vector<char> data; std::copy(str. c_str(), str. c_str()+str. length(), data);

Can a string be a vector?

A vector of strings is created the way a vector of any other type would be created. Remember to make the template specialization, string. Do not forget to include the string library and the vector library. The common ways of creating vectors with string as the element type have been illustrated above.


3 Answers

If you make your template just for type const T& and use the begin(), end(), etc, functions which both vector and string share then your code will work with both types.

like image 91
Zan Lynx Avatar answered Sep 29 '22 10:09

Zan Lynx


Go STL way and use iterators. Accept iterator to begin and iterator to end. It will work with all possible containers, including non-containers like streams.

like image 38
SergeyA Avatar answered Sep 29 '22 09:09

SergeyA


There is no guarantee the layout of string and vector will be the same. They theoretically could be, but they probably aren't in any common implementation. Therefore, you can't do this safely. See Zan's answer for a better solution.

Let me explain: If I am a standard library implementer and decide to implement std::string like so....

template ...
class basic_string {
public:
    ...
private:
    CharT* mData;
    size_t mSize;
};

and decide to implement std::vector like so...

template ...
class vector {
public:
    ...
private:
    T* mEnd;
    T* mBegin;
};

When you reinterpret_cast<string*>(&myVector) you wind up interpreting the pointer to the end of your data as the pointer to the start of your data, and the pointer to the start of your data to the size of your data. If the padding between members is different, or there are extra members, it could get even weirder and more broken than that too.

So yes, in order for this to possibly work they both need to store contiguous data, but they also need quite a bit else to be the same between the implementations for it to work.

like image 25
David Avatar answered Sep 29 '22 11:09

David