2017-10-23 16 views
3

私はVisual Studio 2008 SP1でコンパイルされる古いプロジェクトのテンプレートクラスを作成しています。テンプレートクラスは、実行中の複数のプロセスのうちnamed file-mapping objectで共有されるデータstructを使用します。したがって、私のIPC_SHARED_DATAメンバーの条件は、コンストラクタを持たないプリミティブなデータ型だけを含むことです。テンプレートクラスメンバーをC++ 03のプリミティブ型のみにすることはできますか?

struct IPC_SHARED_DATA{ 
    //IMPORTANT: All members should not have constructors! 

    int nVal; 
    DWORD dwVal; 
    BYTE bytes[16]; 
}; 

の質問は、私は私のIPC_SHARED_MEMテンプレートクラス内の条件として設定することができ、ありますか?

template <class DATA_T> 
class IPC_SHARED_MEM 
{ 
public: 
IPC_SHARED_MEM() 
: hMutexIpc(NULL) 
, hSharedMemIpc(NULL) 
{ 
    //Initialization 
    //... 
} 
~IPC_SHARED_MEM() 
{ 
} 

// ... other functions 

private: 
    DATA_T data;    //Data being passed in shared memory 
    HANDLE hMutexIpc;   //IPC named mutex for synchronized access to 'data' 
    HANDLE hSharedMemIpc;  //IPC named file mapping object handle 
}; 

そして、それがそのまま使用されます。

IPC_SHARED_MEM<IPC_SHARED_DATA> globalSharedMem; 
+0

明らかに 'std :: is_pod'は疑問ですが、[' boost :: is_pod'](http://www.boost.org/doc/libs/1_65_1/libs/)についてはどうでしょうか? type_traits/doc/html/boost_typetraits/reference/is_pod.html) – Tas

+0

@Tas:Boostは使用しません。その方法はどのように実装されていますか? – c00000fd

+0

プリミティブ型のテンプレートを特殊化してみませんか?なぜ型がないので、 'IPC_SHARED_MEM'は' IPC_SHARED_DATA'へのポインタを使うだけでしょうか? –

答えて

0

C++ 03には本当に一般的なis_pod形質を定義する方法はありません。あなたができることは、プリミティブ型を "ホワイトリストに登録"し、ホワイトリストに登録するユーザークラスを許可することです。たとえば:

struct true_type { 
    static const bool value = true; 
    typedef bool type; 
}; 

例えば:

template<typename T> struct is_pod : public false_type {}; 

#define DEFINE_POD(type) template<> struct is_pod<type> : public true_type {} 
DEFINE_POD(char); // continue with all predefined pod types 

// Somewhere in user code: 
class MyClass { int foo; }; 
DEFINE_POD(MyClass); 

true_typeの場合とfalse_typeあなたは何が必要SFINAEスイッチで簡単にそれらを定義することができ、あなたのライブラリに存在していません。

0

* MS VS 2008 SP1は、具体的には、come withis_podを含む部分TR1の実装を思い出しています。それはstd::tr1::is_podとして利用可能です。間違ったことをして、それが利用できない、MSVCを簡単にテンプレートに変換することができる__is_pod固有提供しません:言っ

// is_pod 
template <typename T> struct my_is_pod { 
    enum { value = __is_pod(T) }; 
}; 

を、私は、VC、2008年にこれらの組み込み関数は偽陽性を作り出すことができることが経験的にリコールdocumentation re intrinsicsはその概念をサポートしています。それに応じて専門化する必要があります。買い手責任負担。

今では、MSVCが当時のコンパイラとしてかなり遅れていたとしても、基本的なTR1タイプのすべての特性をTR1文書で提供されている定義で手作業でバックポートしたり、実装したり、 。私はimplement them on my own following the definitionsに私のcxxomfortライブラリを選択しました。ブーストは基本的には,より正確なものを除いて同様のことを行っています。 is_fundamentalのような基本を定義したら、少なくともis_podのバージョン、またはカスタムのサイドキックの特性を作成することができます。これは、独自の目的にさらに特化することができ、少なくとも誤検出を引き起こしません。

だから、あなたは:は、ブーストを使用することはできませんたとえば場合、あなたはまだでつつくにこれらのライブラリのいずれかからのコードを拾うことができます。

EDIT完全性について:あなたが見れます何

、あなたがis_podの作業バージョンを持っていたら、このようになります。コードです:

template <class DATA_T> 
class IPC_SHARED_MEM 
{ 
static_assert (is_pod<DATA_T>::value, "DATA_T must be a pod type"); 

public: 
IPC_SHARED_MEM() 
: hMutexIpc(NULL) 
, hSharedMemIpc(NULL) 
{ 
    //Initialization 
    //... 
} 
~IPC_SHARED_MEM() 
{ 
} 

// ... other functions 

private: 
    DATA_T data;    //Data being passed in shared memory 
    HANDLE hMutexIpc;   //IPC named mutex for synchronized access to 'data' 
    HANDLE hSharedMemIpc;  //IPC named file mapping object handle 
}; 

そうすれば、あなたのクラステンプレートはDATA_Tの型がis_podの特性を満たしているインスタンス化にのみコンパイルされ、エラーメッセージとともにコンパイルに失敗します。

(ここで私ははい、私もそれを行うC++ 11のstatic_assertのバックポートを前提としています。)

(警告の買い手:私はcxxomfortのデベロッパー、そしてMSVC 2008 なしSP1がの一つであります私のテストベッド環境)

関連する問題