问题
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();
}
回答1:
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.
std::copy(&Source, &Source + sizeof(T), Destination); //Fails..
First, let's talk about pointers in C++.
If you have a pointer to some type T
, let's say T *t
, doing this t + 1
will not shift the pointer over one byte. This is basic pointer arithmetic stuff here; t + 1
will shift it over by sizeof(T)
; that's how pointers have worked since the earliest days of C, let alone C++.
Source
is a T&
, so &Source
is a T*
. Therefore, adding sizeof(T)
to it will increment the pointer by sizeof(T) * sizeof(T)
. That's not what you want.
Second, std::copy
is not memcpy. std::copy
is for copying one collection of values (defined by an input iterator pair) into another collection of values defined by an output iterator. std::copy
requires that the value_type
of the input iterator is implicitly convertible to the value_type
of the output iterator.
The value_type
of a T*
, the input iterator in question, is a T
; T*
's point to T
s. The value_type
of your char*
, your output iterator, is char
. std::copy
is going to try to do effectively this:
char *val;
T *t;
*val = *t;
Even ignoring the fact that these two pointers are uninitialized, this makes no sense. Unless T
has an operator char
conversion operator, you cannot simply take a T
and shove it into a char
. Therefore, you get a compile error. As you should.
If you truly have some T
and want to copy it into a char*
array of the appropriate size (or vice-versa), std::copy
is not the tool you need. The tool you want is std::memcpy
. std::copy
is for copying objects, not copying bytes.
来源:https://stackoverflow.com/questions/12523153/copy-memory-to-stdcopy