14

私はしばらくの間C++の高度な機能を使用しておらず、C ++の知識を更新しています。そうは言っても、特性とポリシーベースのプログラミングの概念は、私が頭を悩ませることができなかったものでした。

それを変えたい。私は汎用コンテナを書いています。コンテナが特定の基本クラスから派生したクラスのみを格納するというポリシーを適用したいと思います。これは、ベクターの境界外のアイテムにアクセスしようとすると、コンテナーが(スローするのではなく)無効なオブジェクトを返すためです。

template <class T>   
class GenericContainer
{
private:
    typedef std::vector<T> TypeVect;
    void addElement(const T& elem);

    TypeVect m_elems;

public:
    unsigned int size() const;
    T& elementAt(const unsigned int pos);
    const T elementAt(const unsigned int pos) const;
};

特性を使用して、このジェネリックコンテナをクラス「ContainerItem」のサブクラスのみを含むように制限するにはどうすればよいですか?

4

4 に答える 4

12

IsDerivedFrom特定のタイプ「D」が別のタイプ「B」を継承する場合にのみインスタンス化できる小さなテンプレートを使用できます(この実装は、今週の素晴らしい達人の記事から引用したものです)。

template<typename D, typename B>
class IsDerivedFrom
{
  static void Constraints(D* p)
  {
    B* pb = p; // this line only works if 'D' inherits 'B'
    pb = p; // suppress warnings about unused variables
  } 

protected:
  IsDerivedFrom() { void(*p)(D*) = Constraints; }
}; 

// Force it to fail in the case where B is void
template<typename D>
class IsDerivedFrom<D, void>
{
  IsDerivedFrom() { char* p = (int*)0; /* error */ }
};

IsDerivedFromこれで、継承を使用してテンプレートを簡単にインスタンス化できます。

template <class T>   
class GenericContainer : public IsDerivedFrom<T, ContainerItem>
{
    ...
};

Tこのコードは、を継承する場合にのみコンパイルされますContainerItem

于 2011-01-21T16:21:33.317 に答える
5

boost :: mplを使用してこれを強制し、コンパイル時に型がベースから継承することをアサートできます。

「自分でロール」するのはかなり簡単です。

template <typename D, typename B>
class is_derived_from {
   class No { };
   class Yes { No no[2]; };

   static Yes Test(B*);
   static No  Test(...);
public:
   enum { inherits = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) };
   static bool is_derived() { return inherits; }
};

これはもともとGoTWから来たと思います。その場合に必要なのは、適切なアサートメカニズムだけです(コンパイル時間はおそらくより良いです)。これに対する通常のトリックは、負のサイズの配列を作成してアサートに失敗するか、1で渡すマクロを作成することです。

于 2011-01-21T16:18:17.723 に答える
3

コンセプトチェックをお探しだと思います。これはC++0xに組み込まれようとしていましたが、延期されました。Boostライブラリには、概念を管理するためのライブラリが含まれていますが、構文のキャンディとはほど遠いものです。

補足:コンテナ内のオブジェクトのスライスに注意してください。基本クラスと派生クラスの両方をコンテナーに格納できるようにする場合は、オブジェクト自体の代わりにポインターを使用してください。

于 2011-01-21T16:19:24.770 に答える
2

タイプ特性とポリシーベースのプログラミングは、別個のトピックです。タイプ特性は、既存のタイプおよび追加情報(組み込み)を含めることができないタイプに関する新しい情報を追加します。ポリシーベースの設計は、さまざまな方法でクラスを組み立ててさまざまな動作を作成できるように、クラスを設計する方法です。これは一種のコンパイル時の状態パターンです。

于 2011-01-21T17:37:03.673 に答える