std::vector memory manipulation with serialization and deserialization
First of all, fundamentally: std::string is a data type to hold text. Exclusively. It should not be used to hold binary data. Use a std::vector&lt;(unsigned) char&gt; for that.

Secondly, you are using heap allocation without needing to:

T* pt = new T(t);


This makes no sense at all, and introduces the potential of a memory leak. You could simply make a copy – but you don’t even need to do that. Just work on the original data.

Next, about naming; it’s general convention in C++ to use underscore_separated_names rather than camelCase or PascalCase. This is only a convention but I’d follow it unless there’s a very compelling reason not to.

Also on the topic of naming: returnSize is redundant, return has no place in the name. Rename it to object_size or something along those lines. You are also inconsistent in your naming convention here.

To get the size of a zero-terminated string, use std::strlen, that’s more efficient than converting to a std::string.

Finally, the code simply doesn’t work. It creates a bit-by-bit shallow representation. That only works for simple composite objects, it no longer works for objects that use pointers or references internally – you’ve already noticed that, because otherwise you wouldn’t need to create a special chase for char* and std::string. Incidentally, for the case of char* you specialise returnSize but for the case of std::string you specialise Serialize and DeSerialize. That’s asymmetrical and means that you have several places that might require changing when new types are added. You should reduce this to a single point which requires specialisation.

Ignoring that, I’d rewrite the code as follows:

#include &lt;algorithm&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;

typedef unsigned char byte_t;
typedef std::vector&lt;byte_t&gt; buffer;

std::size_t object_size(const char* s) {
    return std::strlen(s);
};

template&lt;typename T&gt;
std::size_t object_size(T const&amp; obj) {
    return sizeof(obj);
};

template&lt;typename T&gt;
buffer serialize(const T&amp; obj) {
    std::size_t size = object_size(obj);
    buffer buf(size);

    byte_t const* obj_begin = reinterpret_cast&lt;byte_t const*&gt;(&amp;obj);
    std::copy(obj_begin, obj_begin + size, buf.begin());

    return buf;
};

template&lt;&gt;
buffer serialize&lt;std::string&gt;(std::string const&amp; str) {
    return serialize(str.c_str());
};

template&lt;typename T&gt;
T deserialize(buffer const&amp; buf) {
    return *reinterpret_cast&lt;const T*&gt;(&amp;buf[0]);
}

template&lt;&gt;
std::string deserialize&lt;std::string&gt;(buffer const&amp; buf) {
    return deserialize&lt;char*&gt;(buf);
}

int main() {
    using std::cout;

    int x = 97;
    buffer c = serialize(x);
    cout &lt;&lt; deserialize&lt;int&gt;(c) &lt;&lt; "\n";

    char g = 'g';
    buffer c2 = serialize(g);
    cout &lt;&lt; deserialize&lt;char&gt;(c2) &lt;&lt; "\n";

    std::string k = "blabla";
    buffer c3 = serialize(k.c_str());
    cout &lt;&lt; deserialize&lt;char*&gt;(c3) &lt;&lt; "\n";

    std::string ka = "string";
    buffer c4 = serialize(ka);
    cout &lt;&lt; deserialize&lt;std::string&gt;(c4) &lt;&lt; "\n";
}


… but like I said, this solution doesn’t generalise and is pretty useless in practice. Have a look at Boost.Serialization for a proper implementation. Unfortunately this is quite a complex problem.