Let's decompose how it works:
This is the function declaration. The important point is that P is unrelated to T. So, we need to pay more attention, as some bad things might occur...
template <typename P>
P* Write(P* pData)
{
Let's represent the memory pointed by pData. For the sake of the explanation, I will assume that pData points to a sufficiently large area in the memory (or else Write will probably result in a segfault), and that Vector3<T> is only the size of 3 Ts. In the following, I will take T = float, with sizeof(float) = 4, but my explanations will still be valid with other types. So, here sizeof(Vector3<float>) = 12.
So, here is the memory, |-| is one byte:
|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
^
|
pData : P*
We interpret pData as a pointer to a Vector3<T>. This is bad style in general, as P can be anything.
Vector3<T>* pVector = (Vector3<T>*) pData;
The following line:
*pVector++ = *this;
can be divided in:
*pVector = *this;
pVector++;
*pVector = *this; assign the contents of the vector (*this) to the data. The memory is now:
pVector : Vector3<float>*
|
v
|X|X|X|X|Y|Y|Y|Y|Z|Z|Z|Z|-|-|-|-|-|
^^^^^^^^^^^^^^^^^^^^^^^^^
copied content of the vector
pVector++; increments the vector by 1 * sizeof(Vector3<float>), so it now points to the non-yet-written memory:
pVector : Vector3<float>*
|
v
|X|X|X|X|Y|Y|Y|Y|Z|Z|Z|Z|-|-|-|-|-|
pVector is casted back to P* and returned.
return (P*) pVector;
}
This enables to chain writes, as a write to the returned pointer will not overwrite the first write:
char data[2 * sizeof(Vector3<float>)];
v2.Write(v1.Write(data));
// now data is:
// contents of v2
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// |X1|X1|X1|X1|Y1|Y1|Y1|Y1|Z1|Z1|Z1|Z1|X2|X2|X2|X2|Y2|Y2|Y2|Y2|Z2|Z2|Z2|Z2
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// contents of v1
Now, some flaws:
This function can be useful for io, and is equivalent to a memcpy on the vector. However, it has a lot of flaws, the major one being the template parameter. Writing directly to memory for such operations should use char, and not something else. Writing in memory to overwrite the content of a class (ie, not io) is a very bad practice, (assignment operators are made for such a task, and they are safer). Also, the following example is not self-describing:
vec.Write<MyTimerClass>(pointer); // Does not make sense if you are reading this line for the first time
Secondly, there are problems in copying memory. Here, in the explanations, I assumed Vector3 was a simple type. It is not always the case. If it had virtual functions and members of different sizes, the layout in memory would have been implementation-defined, for example:
X, Y, Z padding
------------------------ ----
|P|P|P|P|X|X|X|X|Y|Y|Y|Y|Z|Z|Z|Z|a|a|.|.
-------- ----
vtable some
pointer other
member
And this is not reliable for io. See this SO question (the accepted answer is: "Here is how it works for msvc"...). And for multiple virtual inheritance it becomes a true nightmare.
By the way, the secure implementation of such a method would have been something like:
template<typename IOBuffer>
bool Write(IOBuffer& buffer)
{
return buffer << X << Y << Z;
}
or better:
virtual bool Write(IOBufferInterface& buffer)
{
return buffer << X << Y << Z;
}
It is way more simple to understand, maintain, debug, etc...