10

私はコンテナクラスを持っています、私たちはそれを呼びます

template <class T> CVector { ... } 

T がポインター型の場合、このクラスで何か違うことをしたいです。たとえば、次のようなものです。

template <class T*> CVector< SomeWrapperClass<T> >;

ここで、 SomeWrapperClass は、そのパラメーターとして指定されたものの型を期待しています。残念ながら、この構文はうまく機能せず、掘り下げても、このようなものを機能させる良い方法は見つかりませんでした。

なぜこのようにするのですか?非常に大きなアプリで、一部のコンテナーが特化している型がポインターである場合とポインターではない場合の動作を変更したい - 理想的には、〜 1,000 の場所を変更せずに変更したいCVector<Object*>vsなどのようなものがあるコードではCVector<int>、部分的な特殊化でゲームをプレイするのが道のりのようでした。

私はここでクラックですか?

4

6 に答える 6

8

私があなたを正しく理解していれば、これはあなたが望むことをするかもしれません:

template<typename T>
class CVector { ... };

template<typename T>
class CVector<T*> : public CVector< SomeWrapperClass<T> > {
public:
  // for all constructors:
  CVector(...) : CVector< SomeWrapperClass<T> >(...) {
  }
};

継承の追加レイヤーを追加CVector<T*>して、CVector< SomeWrapperClass<T> >. T*これは、 の予想されるインターフェイスと に提供されたインターフェイスとの間の完全な互換性を確保するために、追加のメソッドを追加する必要がある場合にも役立ちますSomeWrapperClass<T>

于 2009-07-15T22:17:39.180 に答える
6

これはC ++でうまく機能します...

#include <iostream>

template <class T>
class CVector
{
public:
    void test() { std::cout << "Not wrapped!\n"; }
};

template <class T>
class CVector<T*>
{
public:
    void test() { std::cout << "Wrapped!\n"; }
};

int main()
{
    CVector<int> i;
    CVector<double> d;
    CVector<int*> pi;
    CVector<double*> pd;
    i.test();
    d.test();
    pi.test();
    pd.test();
}
于 2009-07-15T22:32:22.957 に答える
4

あなたが記述した構文を使用してクラスを特殊化できるとは思いません...それがどのように機能するかわかりません。あなたができることは、クラスをポインター用に特化し、生のポインターの周りにラッパー クラスを使用してその中身を再実装することです。参考になるかどうかわかりませんが、この記事ではポインター用のテンプレートの特殊化について説明します。

于 2009-07-15T21:54:46.777 に答える
1

Boost 型特性ライブラリは、これを実現するのに役立ちます。is_pointer型 の特性を確認してください。

#include <boost/type_traits.hpp>
#include <iostream>
#include <vector>

using namespace std;

template <class T>
class CVector {
  public:
    void addValue(const T& t) {
      values_.push_back(t);
    }

    void print() {
      typedef boost::integral_constant<bool,
        ::boost::is_pointer<T>::value> truth_type;

      for (unsigned int i = 0; i < values_.size(); i++) 
        doPrint(values_[i], truth_type());
    }


  private:
    void doPrint(const T& t, const boost::false_type&) {
      cout << "Not pointer. Value:" << t << endl;
    }

    void doPrint(const T& t, const boost::true_type&) {
      cout << "Pointer. Value: " << *t << endl;
    }

    std::vector<T> values_;
 };


int main() {
  CVector<int> integers;
  integers.addValue(3);
  integers.addValue(5);
  integers.print();

  CVector<int*> pointers;
  int three = 3;
  int five = 5;
  pointers.addValue(&three);
  pointers.addValue(&five);
  pointers.print(); 
}
于 2009-07-15T22:34:52.327 に答える
0

テンプレートはそれほど柔軟ではないと思います。

非常に強引なアプローチは、すべてのポインター型に特化することです...これにより、テンプレートを使用する問題が解消されます。

ポインターのベクトルにのみ使用される別の CVector クラスを用意できますか?

于 2009-07-15T21:55:33.297 に答える
0

rlbondの答えに同意します。ご要望に合わせて少し修正しました。CVector は、CVector 自体の派生クラスにすることができます。その後、さまざまなメンバーと関数を使用できます。

#include <iostream>
#include <string>
template <class T>
class CVector
{
public:
    void test() { std::cout << "Not wrapped!\n"; }
    void testParent() { std::cout << "Parent Called\n";}
};

template <class T>
class CVector<T*>:
    public CVector<T>
{
public:
    void test(std::string msg) { std::cout << msg; testParent(); }
};

int main()
{
    CVector<int> i;
    CVector<double> d;
    CVector<int*> pi;
    CVector<double*> pd;
    i.test();
    d.test();
    pi.test("Hello\n");
    pd.test("World\n");
    system("pause");
}
于 2013-01-22T14:13:53.357 に答える