0

私には がtemplateあり、 メソッドT get(int i)とがありset(int i, T val)ます。私は振る舞いではなく議論を変える特性クラスを作らなければなりませsetget

template<typename T,int Roz>
class Wektor{
public:
 T tab[Roz];
 T get(int i)
 {
     return tab[i];
 }
 void set(T val,int i)
 {
     tab[i]=val;
 }
 }

そのため、特性クラスは get と set を変更する必要があります。T が int または double の場合、copy int によってパラメーターを取得します

 int get(int i);
 void set(int val,int i);

ダブル

 double get(int i);
 void set(double val,int i);

他のタイプの場合:

T* get(int i);
void set(T* val,int i);

テンプレートの特殊化ではなく、トレイトで行う必要があること。

だから私はこのようにtratisを書きます:

template<typename T,int Roz>
class traitsWektor
{
public:
T tab[Roz];
T get(int i)
{
    return tab[i];
}
void set(T val,int i)
{
    tab[i]=val;
}
}

だからここで私は立ち往生しました。作ればいいと思う

template<typename T, int Roz>
class Wektor : public traitsWektor<T,Roz>

しかし、私はそれが正しいかどうか確信が持てず、まだトラティスです.

4

3 に答える 3

4

クラス テンプレート (Wektor) とパラメーターの型推論を分離する必要があります。

template <class T>
struct WektorParamTraits {
  typedef T const& type;

  //or if you might have different types as getter return type and setter arg
  typedef T const& getterReturn;
  typedef T const& setterArg;
};

その場合、T は getter/setter 引数の「デフォルト」タイプです。必要なタイプに特化してください。クラス定義は次のようになります。

template<typename T,int Roz>
class Wektor{
  T tab[Roz]; //make member variables private
public:
  typename WektorParamTraits<T>::getterReturn get(int i) //const?
  {
    return tab[i];
  }

  void set(typename WektorParamTraits<T>::setterArg val,int i)
  {
    tab[i]=val;
  }
};

更新:コメントに記載されているように、戻り値の型がポインターの場合など、get および set の他の実装を定義する必要がある場合があります。これを行うには、いくつかの異なるアプローチがあります。

  1. tab[i]と引数/戻り値の間で正しく変換する関数をトレイトに定義します。
  2. ポインターと非ポインターのみに関する場合は、getter と setter の 2 つのバージョンを提供し、そのうちの 1 つを無効にするために必要なものを使用しますstd::enable_ifstd::is_pointer
  3. ここに投稿した単純なクラス定義を使用して、通常の参照を使用しないいくつかの型に特化します。それ以上の機能は、特殊化されていないサブクラスに入れる必要があります。

アプローチ 2 は非常に冗長で読みにくいものです。アプローチ 1 も同様に冗長であり、配列定義を除くほとんどすべてをその特性クラスに委譲するため、アプローチ 3 を使用することもできます。

于 2013-04-15T11:33:28.400 に答える
0

このテンプレートが役立つと思います:

template<typename T>
class traits
{
public:
    typedef T * result;
};

template<>
class traits<int>
{
public:
    typedef int result;
};

template<>
class traits<double>
{
public:
    typedef double result;
};


traits<int>::result; // is int.
traits<char>::result; // is char *.
于 2013-04-15T11:40:49.957 に答える
0

どのように実装したいかわかりませんset(T*,int)。しかし、getあなたはこれを試してみたいかもしれません

template<typename T, size_t Roz>
class Wektor
{
public:
    template<typename U=T>
    typename std::enable_if<std::is_arithmetic<U>::value, U>::type 
        Get(size_t n)
    { 
        return tab[n];
    }

    template<typename U=T>
    typename std::enable_if<!std::is_arithmetic<U>::value, U*>::type 
        Get(size_t n)
    { 
        return &tab[n];
    }

    T tab[Roz];
};
于 2013-04-15T11:41:35.123 に答える