0

我正在尝试将我所有的 CopyMemory 函数转换为 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::copy 的代码如下(如果有效则打印 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();
}
4

1 回答 1

8

这段代码有很多问题,几乎不可能知道从哪里开始。在许多情况下,这些错误是如此基本,以至于暴露出对你应该做什么的严重误解。你写的那种代码对于有经验的 C++ 程序员来说是危险的;您在代码中犯的错误表明您还没有经验。

停止尝试做你想做的事情。

但是让我们拿你的代码。

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

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

如果你有一个指向某种类型的指针T,比如说T *t,这样做t + 1不会指针移过一个字节。这是这里的基本指针算术内容;t + 1将其转移sizeof(T);从 C 的早期开始,指针就是这样工作的,更不用说 C++了。

Source是 a T&&Sourcea 也是T*。因此,添加sizeof(T)它会使指针增加sizeof(T) * sizeof(T). 那不是你想要的。

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

value_typea T*,有问题的输入迭代器,是 a T; T*的指向Ts。value_type您的char*输出迭代器是char. std::copy将尝试有效地做到这一点:

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

即使忽略这两个指针未初始化的事实,这也没有任何意义。除非Toperator char转换运算符,否则您不能简单地将 aT放入 achar中。因此,您会收到编译错误。正如你应该的那样。

如果您确实有一些T并想将其复制到char*适当大小的数组中(反之亦然),std::copy则不是您需要的工具。你想要的工具是std::memcpy. std::copy用于复制对象,而不是复制字节。

于 2012-09-21T04:41:52.640 回答