Ich entwickle eine Containervorlagenklasse. Dieser Code muss mit dem vorhandenen C-Code eine Schnittstelle bilden und muss binärkompatibel bleiben, so dass ich z. B. std::vector
oder ähnliches nicht verwenden kann.Wählen Sie eine Methode als (Standard) Vorlagenparameter
Das Problem, das ich habe, ist, dass es unterschiedliche Allokationsstrategien unterstützen muß, und ich weiß nicht, wie der allocator als Vorlage Argument zu liefern. Ich habe eine SSCCE
erstellt, um zu veranschaulichen, wie weit ich gekommen bin (was natürlich nicht kompiliert, denn wenn es so wäre, müsste ich diese Frage nicht stellen :)).
#include <iostream>
#include <cstring>
#include <type_traits>
typedef unsigned int uint_t;
typedef signed int int_t;
template <typename T, typename S, typename _allocator = _virtual>
class Container
{
public:
Container(S nItems = 0, S nMaxItems = 0, T *pArray = NULL)
{
mItems = nItems;
mMaxItems = nMaxItems;
mArray = pArray;
}
void adjustMalloc(uint_t nClusterSize)
{
if(mItems == mMaxItems)
{
mArray = (T *)realloc(mArray, (mMaxItems+nClusterSize)*sizeof(T));
mMaxItems += nClusterSize;
}
}
void adjustAligned(uint_t nClusterSize)
{
if(mItems == mMaxItems)
{
mArray = (T *)_aligned_realloc(mArray, (mMaxItems+nClusterSize)*sizeof(T), 16);
mMaxItems += nClusterSize;
}
}
void adjustVirtual(uint_t nClusterSize)
{
if(mItems == mMaxItems)
{
mArray = VirtualAlloc(mArray, (mMaxItems+nClusterSize)*sizeof(T), MEM_RESERVE, PAGE_NOACCESS);
mMaxItems += nClusterSize;
}
}
void adjust(uint_t nClusterSize)
{
if (std::is_same<_allocator>::value == _virtual)
adjustVirtual(nClusterSize);
else if(std::is_same<_allocator>::value == _aligned)
adjustAligned(nClusterSize);
else if(std::is_same<_allocator>::value == _malloc)
adjustMalloc(nClusterSize);
else
{
// Cause a static compiler error, how?
}
}
bool add(T *pItem)
{
if(find(pItem) == NULL)
{
adjust(100);
mItems++;
return true; // added
}
return false;
}
T *find(T *pItem)
{
T *p = mArray;
for(S i = 0; i < mItems; i++, p++)
{
if(*p == *pItem)
return p;
}
return NULL;
}
private:
S mItems;
S mMaxItems;
T *mArray;
};
class Record
{
public:
bool operator==(const Record &oRecord)
{
if(Id != oRecord.Id)
return false;
if(strcmp(Name, oRecord.Name) != 0)
return false;
return true;
}
int Id;
char Name[10+1];
};
int main(int argc, char *argv[])
{
Record rec;
rec.Id = 0;
strcpy(rec.Name, "Test");
Container<Record, uint_t> records; // Default using malloc
records.add(&rec);
if(records.find(&rec) == NULL)
std::cerr << "Not found" << std::endl;
Container<Record, uint_t, _virtual> vrecords; // VirtualAlloc allocator used.
vrecords.add(&rec);
if(records.find(&rec) == NULL)
std::cerr << "Not found" << std::endl;
return 0;
}
Ich verwende Visual Studio 2010, also ist es nicht 100% C++ 11.
Die VirtualAlloc
ist ebenso (andere) Beispiel und wird nicht funktionieren, wie es hier dargestellt ist.
Wie löst die Neuimplementierung von 'vector' Ihr Schnittstellenproblem? – Barry
Ist das relevant für eine Antwort? – Devolus
Ja. Gerade jetzt hat dein 'Container' einige Probleme, also würde ich gerne verstehen, was dieser Ansatz dir wirklich bringt, dass' vector' einfach nicht verwendet wird (oder 'std :: set'), basierend auf dem, was' add' tut) – Barry