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行ってもポインターが1バイト以上シフトすることはありません。これは基本的なポインター演算です。でシフトオーバーします。これが、C++ は言うまでもなく、C の初期の頃からポインターが機能してきた方法です。t + 1t + 1sizeof(T)

Sourceはです。T&_ したがって、それに追加すると、ポインタが だけインクリメントされます。それはあなたが望むものではありません。&SourceT*sizeof(T)sizeof(T) * sizeof(T)

第二に、std::copy memcpy ではありませんstd::copy値の 1 つのコレクション (入力イテレーターのペアによって定義される) を、出力イテレーターによって定義される別の値のコレクションにコピーするためのものです。std::copyではvalue_type、入力反復子の が出力反復子の に暗黙的に変換可能である必要がvalue_typeあります。

問題の入力イテレータである a の は avalue_typeです。の s へのポイント。出力イテレータのはです。これを効果的に実行しようとしています:T*TT*Tvalue_typechar*charstd::copy

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

これら 2 つのポインターが初期化されていないという事実を無視しても、これは意味がありません。T変換演算子がない限り、単純に aを に押し込むoperator charことはできません。したがって、コンパイル エラーが発生します。あなたがすべきように。Tchar

本当にいくつか持っていて、それを適切なサイズTの配列にコピーしたいchar*場合 (またはその逆) は、std::copy必要なツールではありません。欲しいツールはstd::memcpy. バイトのコピーではなく、オブジェクトstd::copyのコピー用です。

于 2012-09-21T04:41:52.640 に答える