2012-09-21 118 views
0

我试图将我所有的CopyMemory函数转换为std :: copy函数。将内存复制到std :: copy

它适用于copymemory和memcpy,但不适用于std :: copy。任何人都可以告诉我我做错了什么或如何解决它?

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); 
} 

我也想通,我可以做以下的迭代器转换为指针:

std::string Foo = "fdsgsdgs"; 

std::string::iterator it = Foo.begin(); 

unsigned char* pt = &(*it); 

我将如何转换指针迭代器呢? :S

我用它来测试的memcpy/copymem VS的std ::复制如下(它打印出7,如果它的工作原理..和随机数,如果它不)代码:

#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

[RTFM](http://www.cplusplus.com/reference/algorithm/copy/):目标必须是输出迭代器 –

+0

嗯,所以我不能使用它,因为我没有迭代器:我想我会坚持使用memcpy。 – Brandon

+2

你得到了什么错误?我看到的关于你的唯一奇怪的东西是代码(除了S和D之外)是你可以模拟源类型或目标类型,但是如果类型不匹配,你会得到一个编译,因为std: :复制是类型安全的。 – user1610015

回答

8

这段代码有太多的错误,所以几乎不可能知道从哪里开始。而且这些错误在很多情况下都非常基本,以至于对您应该做的事情有严重的误解。您正在编写的代码对于有经验的C++程序员来说是危险的;你在代码中犯的错误表明你远没有经验。

不要试图做你想做的事情。

但让我们拿你的代码。

std::copy(&Source, &Source + sizeof(T), Destination);  //Fails.. 

首先,让我们来谈谈C++中的指针。

如果你有一个指向某种类型的T,让我们说T *t,这样t + 1移指针移到一个字节。这里是基本指针算术的东西; t + 1将改变sizeof(T);这就是C指针早期的工作方式,更不用说C++了。

SourceT&,所以&SourceT*。因此,向其添加sizeof(T)将使指针增加sizeof(T) * sizeof(T)。这不是你想要的。

二,std::copy不是memcpystd::copy用于将一个值集合(由输入迭代器对定义)复制到另一个由输出迭代器定义的值集合中。 std::copy要求输入迭代器的value_type隐式转换为输出迭代器的value_type

所述输入迭代器T*value_typeT; T*指向T s。您的输出迭代器char*value_typecharstd::copy是要尝试有效这个来做:

char *val; 
T *t; 
*val = *t; 

即使忽略的事实,这两个指针是未初始化的,这是没有意义的。除非T有一个operator char转换算子,您不能简单地拿一个T并将其推入char。因此,你会收到一个编译错误。正如你应该的。

如果您真的有一些T并且想将其复制到char*相应大小的阵列中(反之亦然),则std::copy不是您需要的工具。你想要的工具是std::memcpystd::copy用于复制对象,不复制字节。

+0

很好的答案,但我想补充说,'std :: copy(reinterpret_cast (&t),reinterpret_cast (&t)+ sizeof(t),dest)'确实可以达到这个目的。 ;) – Xeo

+0

@Xeo:每当我看到'reinterpret_cast'我的眼睛都受伤......除此之外,*确实为此目的而工作*是一个非常大胆的陈述。我可以给你几个'T'类型,它根本不起作用(实际上不是标准布局类型的东西)。除此之外,如果你打算使用'memcpy',只需使用'memcpy',它至少会在代码中清楚你正在为许多类型做一些潜在的危险事情。用'std :: copy'写'memcpy'并不会降低它的危险性,并且确实使它更难以发现(并且可能更慢)。 –

+0

@David:对不起,我认为最后的“;)”清楚地表明,它大部分是口舌和开玩笑。当然,我知道这只会造成问题。 :) – Xeo

相关问题