2016-04-14 13 views
-1

私はコンテナテンプレートクラスを開発しています。このコードは既存のCコードとのインターフェースを必要とし、バイナリ互換性を保つ必要があるため、std::vectorなどを使用することはできません。(デフォルトの)テンプレートパラメータとしてメソッドを選択してください

問題は、異なる割り当て戦略をサポートする必要があり、テンプレート引数としてアロケータを提供する方法がわかりません。私はどれくらいの距離を持っているかを示すためにSSCCEを作成しました(もしそうなら、私はこの質問をする必要はないので、コンパイルできません:))。

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

私はVisual Studio 2010を使用しているので、100%C++ではありません。

VirtualAllocは(別の)例として提供されており、ここに示すように動作しません。

+0

どのように再実装する 'vector'はあなたのインターフェースの問題を解決しますか? – Barry

+0

これは回答に関連していますか? – Devolus

+0

はい。今では 'Container'にはいくつかの問題がありますので、' vector'を使用するだけでは実際にあなたが得られるアプローチを理解したいと思います( 'add'が何であるかに基づいて' std :: set')。 – Barry

答えて

-1

私の問題の解決策が見つかりました。しかし、私は警告if(std::is_same...ためadjust()方法で

warning C4127: conditional expression is constant

を取得し、これが正常であるか、私はそれを無効にする以外に、それを取り除くことができるかどうかと思いまして。

#include "stdafx.h" 
#include "windows.h" 

#include <iostream> 
#include <cstring> 
#include <type_traits> 

#pragma warning (push) 
//#pragma warning (disable : 4127) 

typedef unsigned int  uint_t; 
typedef signed int   int_t; 

typedef struct { const static bool _virtual_allocator = true; } _virtual_type; 
typedef struct { const static bool _aligned_allocator = true; } _aligned_type; 
typedef struct { const static bool _malloc_allocator = true; } _malloc_type; 

template <typename T, typename S, typename _allocator = _aligned_type> 
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 = (T *)VirtualAlloc((LPVOID)mArray, (mMaxItems+nClusterSize)*sizeof(T), MEM_RESERVE, PAGE_NOACCESS); 
      mMaxItems += nClusterSize; 
     } 
    } 

    void adjust(uint_t nClusterSize) 
    { 
     if (std::is_same<_allocator, _virtual_type>::value) 
      adjustVirtual(nClusterSize); 
     else if(std::is_same<_allocator, _aligned_type>::value) 
      adjustAligned(nClusterSize); 
     else if(std::is_same<_allocator, _malloc_type>::value) 
      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; 
}; 

#pragma warning (pop) 

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> mrecords; 
    mrecords.add(&rec); 

    if(mrecords.find(&rec) == NULL) 
     std::cerr << "Malloc Not found" << std::endl; 

    Container<Record, uint_t, _aligned_type> arecords; 
    arecords.add(&rec); 

    if(arecords.find(&rec) == NULL) 
     std::cerr << "Aligned Not found" << std::endl; 

    Container<Record, uint_t, _virtual_type> vrecords; 
    vrecords.add(&rec); 

    if(vrecords.find(&rec) == NULL) 
     std::cerr << "Virtual Not found" << std::endl; 

    return 0; 
} 
+0

なぜdownvote? – Devolus

関連する問題