1

テンプレートの特殊化をテストするために書いていた次のコードがあります。テンプレート パラメーター推定を使用して M と N を取得し、2 次元配列の行と列を取得できるように、ポインターを型に減衰させる方法はありますか? 2 次元配列に対して vector の vector を実行できることはわかっていますが、これはテンプレートの特殊化の演習です。次のコードはそのまま機能しますが、次のコメントを外して現在の T** コンストラクターをコメントアウトすると、機能しません。その結果、コンストラクターは現在、data_ メンバーを削除するために使用される行数をハード コードしています。これは理想的ではなく、理想的には、テンプレート推定からこのパラメーターを取得します。以下に示す次のコードでこれを機能させる方法があるかどうか疑問に思っていました。

        //doesn't like this constructor
    //  template <unsigned int M, unsigned int N>
    //  Data ( T (&d)[M][N]  ): data_(d), rows_(M), cols_(N) {};

#include <iostream>

template <typename T>
class Data
{
  public:
  Data ( const T& d ): data_(d) {};
  Data ( T&& d ): data_(std::move(d)) {};

  std::string getType() { return "Plain Data Type"; }

  private: 
  T  data_;
};


template <typename T>
class Data<T**>
{
  public:

    //doesn't like this constructor
//  template <unsigned int M, unsigned int N>
//  Data ( T (&d)[M][N]  ): data_(d), rows_(M), cols_(N) {};
  Data ( T** d ): data_(d), rows_(25) {};
  ~Data() { 

    for ( unsigned int i = 0; i < rows_; ++i)    
    {
      delete [] data_[i];
    }
    delete [] data_;
  }

  std::string getType() { return "Pointer to Pointer Data Type"; }

  private:
  T**  data_;
  unsigned int rows_;
  unsigned int cols_;
};


template <typename T>
class Data<T*>
{
  public:
  Data ( T* d ): data_(d) {};
  ~Data() { delete data_; }

  std::string getType() { return "Pointer Data Type"; }

  private:
  T*  data_;
};


int main ( int argc, char *argv[])
{
  float f(9.65);
  Data<int> d1(f);
  std::cout << d1.getType() << std::endl;

  int *i = new int(5);
  Data<int*> d2(i);
  std::cout << d2.getType() << std::endl;

  int **j = new int*[25];
  for ( int i = 0 ; i < 25; ++i)
    j[i] = new int[50];

  Data<int**> d3(j);
  std::cout << d3.getType() << std::endl;
}


output:
Plain Data Type
Pointer Data Type
Pointer to Pointer Data Type
4

1 に答える 1

2

T**T[n][m]は同等ではありません (そして、これを教えることを拒否する大学教授を呪います)。1 つはポインタからポインタへ、もう 1 つはT[m]sizeの配列ですn

次のように、2D 配列タイプを特殊化できます。

template<typename T, size_t N, size_t M>
class Data<T[N][M]>
{
public:
    Data(const T(&ar)[N][M])
    {
        for (size_t i=0;i<N;++i)
            std::copy(std::begin(ar[i]), std::end(ar[i]), std::begin(data[i]));
    }

    std::string getType() { return "2D-Fixed Array Data Type"; }

private:
    T data[N][M];
};

そして、それを使用する1つの方法は次のとおりです。

float fdat[10][20];
Data<decltype(fdat)> d4(fdat);
std::cout << d4.getType() << std::endl;

出力

2D固定配列データ型

于 2013-09-12T05:19:14.543 に答える