As piotr already suggested: try using existing libraries to marshall.
However, since your already doing it yourself:
If your supported primitives are representable as bytes, then you shouldn't be bit packing (there might be some confusion about the term), otherwise consider using std::bitset.
Because C++ doesn't support reflection, there is no help in C++ to byte pack structures in a generic, safe and portable way, so be prepared to write a function per structure to pack each primitive and each member structure.
Overloading does help to call these functions in a generic way, so packing of containers (vector ...) can be done generically. However, if you want this, then prefer free functions over member functions, to avoid having a difference between packing primitives and packing structures.
Example:
void Pack(const MyStruct& str, Packer& pack)
{
Pack(str.int1, pack);
Pack(str.string1, pack);
Pack(str.otherStruct, pack);
}