2012-04-13 28 views
0

私はこのキュークラスを持っていますが、実際には同じ問題を抱えるものがいくつかあります。長いコピーを持つタイプでコンパイルするとパフォーマンスが悪くなります。キューはプッシュ/ポップ時にロックされ、競合の可能性が高くなります。開発者の中には、(ポインタの代わりに)10MBのバッファクラスでコンパイルしようとすると、クラスがコンパイルされない場合に便利です。ポインタでないテンプレートクラスの例外を発生させますか?

テンプレートパラメータを基底クラスまたは他の型に制限する簡単な方法はないようです。

パラメータがクラスインスタンスへのポインタでない場合、クラスがコンパイルされないようにするために使用できるボギーがありますか?

+2

あなたはおそらく、その後、移動ctorsをサポートする必要があります。 10 MBのバッファークラスを移動することは、まったく高価である必要はありません。 – MSalters

答えて

5

これはいくつかの方法で行うことができます。別の答えとして、static_assert(できればroll your ownでも可能ですが、C++ 11/Boostから)を使うことができますが、実際にはポインタでありサイズだけに依存していないかどうかを確認することをおすすめします。あなたは、独自のロールまたは使用しているもののシステムに応じて、existing trait(あまりにも利用可能in C++11)を使用することができ、次のいずれか

template <typename T> 
struct is_pointer { 
    enum { value = 0 }; 
}; 

template <typename T> 
struct is_pointer<T*> { 
    enum { value = 1 }; 
}; 

template <typename T> 
struct container { 
    static_assert(is_pointer<T>::value, "T must be a pointer"); 
    void push(const T&); 
    T pop(); 
}; 

struct foo {}; 

int main() { 
    container<foo*> good; 
    container<foo> fail; 
} 

しかし、それは大きなポイントを発生させます。あなたの要求が、あなたが物事を指し示すことだけであるならば、そのようなテンプレートパラメータをまず解釈するのはどうですか?例えば。あなたのコンテナを作る:

template <typename T> 
struct container { 
    void push(const T*); 
    T *pop(); 
}; 

最初に非ポインタ型を指定できるようにするのではなく、

template <typename T> 
struct container; 

template <typename T> 
struct container<T*> { 
    void push(const T*); 
    T *pop(); 
}; 

struct foo {}; 

int main() { 
    container<foo*> good; 
    container<foo> fail; 
} 

をこれはまだ明示的に必要となって:あなただけではなく例えば、非ポインタのためにそれを実装するあなただけのポインタ型のコンテナを特化することができますstatic_assertの道を行くにしたくない場合は最後に

ポインタをタイプすると、非ポインタ型のコンパイル時に失敗しますが、static_assertや型がポインタであるかどうかを判断する必要はありません。

+0

これは古い質問ですが、C++ 11ではstd :: is_pointerを追加しました http://www.cplusplus.com/reference/type_traits/is_pointer/ – Jameshobbs

0

静的なアサートの変形を使用します(多くの可能な実装ではgoogleだけです)。 BOOST_STATIC_ASSERT(sizeof(T) <= sizeof(void*))のようなものは、そのトリックを行う必要があります。

+0

ちょうどTが小さいからといって、それが簡単なコピーコンストラクタを持っているわけではありません。 – Flexo

+0

Hmh、そうです。しかし、型が、例えばプリミティブ型であるかどうかを判断するための特性ヘルパークラスもあります。したがって、sizeofテストの代わりにこれを置き換えることができます。 – zvrba

0

はい、static_assertを使用して行うことができます。たとえば、

2

"パラメータがクラスインスタンスへのポインタでない場合、クラスがコンパイルされないようにするために使用できるボギーがありますか?"

ないbodge、しかし:

template<class T> 
class MyContainer 
{ 
public: 
    void AllMemberFunctions(T* in){} 
    void OnlyAcceptTStars(T* in){} 

}; 

ユーザーが開催されているタイプを定義し、あなたの機能だけでそのタイプへのポインタを受け入れるか、または扱います。

(あるいは、どのようなSTLのユーザーの一部にいくつかのインテリジェンスを前提として問題を忘れないでください。)

関連する問題