2

私はこのキュー クラスを持っています。実際には、同じ問題に苦しむいくつかのクラスがあります - 長いコピー ctor を持つ型でコンパイルするとパフォーマンスが低下します - キューはプッシュ/ポップ中にロックされ、ロックされている時間が長いほど、競合の可能性が高くなります。一部の開発者が (ポインタではなく) 10MB のバッファ クラスを使用してクラスをコンパイルしようとした場合に、クラスがコンパイルされない場合に役立ちます。

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

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

4

4 に答える 4

6

これはいくつかの方法で行うことができます。別の回答が指摘しているように、 static_assert でそれを行うことができます (できれば C++ 11/Boost から、自分でロールすることもできます) が、サイズだけに依存するのではなく、実際にポインターであるかどうかを確認することをお勧めします。使用しているシステムに応じて、独自の特性をロールするか、既存の特性( 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();
};

そもそもポインタ以外の型を指定できるようにする代わりに?

最後に、 static_assert の道をたどりたくない場合は、コンテナーをポインター型のみに特化し、非ポインターには実装しないようにすることができます。

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 または型がポインターであるかどうかを判断する方法は必要ありません。

于 2012-04-13T14:18:33.817 に答える
2

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

ボッジではありませんが、次のとおりです。

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

};

ユーザーは保持される型を定義し、関数はその型へのポインターのみを受け入れまたは処理します。

(または、STL が行うことを行い、ユーザー側の知性を想定して、問題を忘れてください。)

于 2012-04-13T14:24:00.677 に答える
0

静的アサーションのバリアントを使用します(多くの可能な実装についてはグーグルだけです)。のようなものBOOST_STATIC_ASSERT(sizeof(T) <= sizeof(void*))がトリックを行う必要があります。

于 2012-04-13T14:07:26.477 に答える
0

はい、static_assertを使用して実行できます。例えば、

template<int N>
class Queue
{
static_assert(N < size, "N < size violated");
...
};
于 2012-04-13T14:09:51.870 に答える