let your std::vector(or something else) compatible with stream operator <<

Not a quite secret, just have some operator overload trick.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
std::vector<char>& operator<<(std::vector<char>& target, const char* word) {
target.insert(target.end(), word, word + std::strlen(word));
return target;
}
std::vector<char>& operator<<(std::vector<char>& target, char word) {
target.push_back(word);
return target;
}
std::vector<char>& operator<<(std::vector<char>& target, const std::string& word) {
return (target << word.c_str());
}

This method have several benefit, first, std::vector can be inserted in templated class, to replace any stream :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template<typename ContinerType>
class {
public:
void somethingBalabala(const std::string& source) {
ContainerType container;
container << source;
}
};
std::string aString("I am a string");
SomethingFooFooFoo<std::iostream> something;
something.somethingBalabala(aString); //Works
SomethingFooFooFoo<std::vector> somethingElse;
somethingElse.somethingBalabala(aString); //also works

It can load up data into container, with controlled type. If you wish, you can even load any byte data into it(using first two implementations). Unloading a vector is quite easy, just use

1
const signed char* dumpData = (const signed char*)vectorContainer.data();

It’s easy, but there is 2 important highlight and ignoring these will easily mess up your code:

  1. This data have the same life cycle with the vector container, if the vector is destoryed, this data will no longer valid.
  2. This data should use const to get the data! missing const will directly changes data in vector, and cause unexpected side effect, be advised!

For sake of safely, you should get this data via memcpy, or you know what you are doing. in general case, put both dumpData and vectorContainer in the same scope is a good idea, and it is common sense that you should not pass dumpData with pointer to outside of the scope.