I’m trying to convert all my CopyMemory functions to std::copy functions.
It works with copymemory and memcpy but not std::copy. Can anyone tell me what I’m doing wrong or how to fix it?
template<typename T>
void S(unsigned char* &Destination, const T &Source)
{
//CopyMemory(Destination, &Source, sizeof(T));
std::copy(&Source, &Source + sizeof(T), Destination); //Fails..
Destination += sizeof(T);
}
template<typename T>
void D(T* &Destination, unsigned char* Source, size_t Size)
{
//CopyMemory(Destination, Source, Size);
std::copy(Source, Source + Size, Destination);
Source += sizeof(T);
}
template<typename T>
void D(T &Destination, unsigned char* Source, size_t Size)
{
//CopyMemory(&Destination, Source, Size);
std::copy(Source, Source + Size, &Destination);
Source += sizeof(T);
}
I’ve also figured that I could do the following to convert iterators to pointers:
std::string Foo = "fdsgsdgs";
std::string::iterator it = Foo.begin();
unsigned char* pt = &(*it);
How would I convert pointers to iterators then? :S
The code I use to test the memcpy/copymem vs std::copy is as follows (It prints 7 if it works.. and random numbers if it doesn’t):
#include <windows.h>
#include <iostream>
#include <vector>
#include <typeinfo>
using namespace std;
typedef struct
{
int SX, SY;
uint32_t Stride;
unsigned long ID;
int TriangleCount;
} Model;
template<typename T>
void S(unsigned char* &Destination, const T &Source)
{
CopyMemory(Destination, &Source, sizeof(T));
Destination += sizeof(T);
}
template<typename T>
void S(unsigned char* &Destination, const std::vector<T> &VectorContainer)
{
size_t Size = VectorContainer.size();
for (size_t I = 0; I < Size; ++I)
S(Destination, VectorContainer[I]);
}
void S(unsigned char* &Destination, const Model &M)
{
S(Destination, M.SX);
S(Destination, M.SY);
S(Destination, M.Stride);
S(Destination, M.ID);
S(Destination, M.TriangleCount);
}
template<typename T>
void D(T* &Destination, unsigned char* Source, size_t Size)
{
CopyMemory(Destination, Source, Size);
Source += sizeof(T);
}
template<typename T>
void D(T &Destination, unsigned char* Source, size_t Size)
{
CopyMemory(&Destination, Source, Size);
Source += sizeof(T);
}
template<typename T>
void D(std::vector<T> &Destination, unsigned char* Source, size_t Size)
{
Destination.resize(Size);
for(size_t I = 0; I < Size; ++I)
{
D(Destination[I], Source, sizeof(T));
Source += sizeof(T);
}
}
void D(Model* &Destination, unsigned char* Source)
{
D(Destination->SX, Source, sizeof(Destination->SX));
D(Destination->SY, Source, sizeof(Destination->SY));
D(Destination->Stride, Source, sizeof(Destination->Stride));
D(Destination->ID, Source, sizeof(Destination->ID));
D(Destination->TriangleCount, Source, sizeof(Destination->TriangleCount));
}
long double* LD = new long double[25000];
std::vector<Model> ListOfModels, ListOfData;
void ExecuteCommands()
{
switch(static_cast<int>(LD[1]))
{
case 1:
{
LD[2] = 2;
unsigned char* Data = reinterpret_cast<unsigned char*>(&LD[3]);
Model M; M.SX = 1; M.SY = 3; M.Stride = 24; M.ID = 7; M.TriangleCount = 9;
Model K; K.SX = 3; K.SY = 21; K.Stride = 34; K.ID = 9; K.TriangleCount = 28;
ListOfModels.push_back(M);
ListOfModels.push_back(K);
S(Data, ListOfModels);
}
break;
}
}
void* GetData()
{
unsigned char* Data = reinterpret_cast<unsigned char*>(&LD[3]);
D(ListOfData, Data, LD[2]);
cout<<ListOfData[0].ID; //Should print 7 if it works.
return &ListOfData[0];
}
int main()
{
LD[1] = 1;
ExecuteCommands();
GetData();
}
There are so many things wrong with this code that it’s almost impossible to know where to begin. And the errors are in many cases so basic that it betrays a gross misunderstanding of what you should be doing. The kind of code you’re writing is dangerous for experienced C++ programers; the errors you’ve made in your code suggest that you’re far from experienced.
Stop trying to do what you’re trying to do.
But let’s take your code.
First, let’s talk about pointers in C++.
If you have a pointer to some type
T, let’s sayT *t, doing thist + 1will not shift the pointer over one byte. This is basic pointer arithmetic stuff here;t + 1will shift it over bysizeof(T); that’s how pointers have worked since the earliest days of C, let alone C++.Sourceis aT&, so&Sourceis aT*. Therefore, addingsizeof(T)to it will increment the pointer bysizeof(T) * sizeof(T). That’s not what you want.Second,
std::copyis not memcpy.std::copyis for copying one collection of values (defined by an input iterator pair) into another collection of values defined by an output iterator.std::copyrequires that thevalue_typeof the input iterator is implicitly convertible to thevalue_typeof the output iterator.The
value_typeof aT*, the input iterator in question, is aT;T*‘s point toTs. Thevalue_typeof yourchar*, your output iterator, ischar.std::copyis going to try to do effectively this:Even ignoring the fact that these two pointers are uninitialized, this makes no sense. Unless
Thas anoperator charconversion operator, you cannot simply take aTand shove it into achar. Therefore, you get a compile error. As you should.If you truly have some
Tand want to copy it into achar*array of the appropriate size (or vice-versa),std::copyis not the tool you need. The tool you want isstd::memcpy.std::copyis for copying objects, not copying bytes.