1

多くの型 {int, float, double} を扱うために、C ++ テンプレートを使用して配列のライブラリを開発しました。構造体と関数の定義と宣言をファイル Util.h と Util.cpp に格納します。そして、それを arraySample.cpp で呼び出します。ただし、プロジェクトをコンパイルできません。g ++は、printArrayへの未定義の参照を言う

エラーメッセージ

make all 
g++ -O2 -g -Wall -fmessage-length=0   -c -o arraySample.o arraySample.cpp
g++ -O2 -g -Wall -fmessage-length=0   -c -o Util.o Util.cpp
g++ -o arraySample arraySample.o Util.o 
arraySample.o: In function `main':
/home/vtvan/Desktop/workspace/arraySample/arraySample.cpp:15: undefined reference to `int printArray<double>(Array<double>)'
/home/vtvan/Desktop/workspace/arraySample/arraySample.cpp:22: undefined reference to `int printArray<int>(Array<int>)'
collect2: ld returned 1 exit status
make: *** [arraySample] Error 1

この問題を解決するのを手伝ってください。何度も試しましたが、修正できません。3つのファイルを組み合わせるとうまくいくのは非常に奇妙です。そこで、いくつかの解決策を教えてください。参考までに 3 つのファイルのソース コードをここに添付します。

どうもありがとうございました。返信をお待ちしております。

Util.h

#ifndef UTIL_H_
#define UTIL_H_

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <typeinfo>

#define ARRAYMAXNDIMS 3

// multi-dimensional array 
template <typename T>
struct Array {
   T *x;
   int size;
   int nDims;
   int N[ARRAYMAXNDIMS];
};
template <typename T> int printArray(Array<T> A);

#endif /* UTIL_H_ */  

ユーティリティ.cpp

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <typeinfo>

#include "Util.h"

template <typename T> int printArray(Array<T> A) {

  int i = 0, j = 0;
  int k,l;

  std::string typeT = typeid(T).name();

  std::string format("  %9f");

  if (!typeT.compare("i"))
          format = "  %d";

  printf("Array with dimension (%d",A.N[0]);
  k=1;
  while(k<A.nDims && k<ARRAYMAXNDIMS){
    printf(",%d",A.N[k]);
    k++;
  }
  printf(")\n");

  switch (A.nDims) {
  case 1: // print 1D array
    for(k=0;k<A.N[0];k++){ printf("  %9d",A.x[k]);}
    printf("\n");
    return(1);
  case 2: // print 2D array
    for(k=0;k<A.N[0];k++){

      for(l=0;l<A.N[1];l++) {

          printf(format.c_str(),A.x[k+l*A.N[0]]);
      }
      printf("\n");
    }
    return(1);
  case 3: // print last 2 dimensions of a 3D array, where the index of the first dimension is i
    if(i<0 || i>=A.N[0]) {
      printf("index %d is outside the range of indices for the first dimension, i.e. [0:%d]\n",i,A.N[0]-1);
      return(0);
    }
    printf("printing slice (%d,:,:)\n",i);
    for(k=0;k<A.N[1];k++){
//      printf("%5d   ",k);
      for(l=0;l<A.N[2];l++) printf("  %9d",A.x[i+k*A.N[0]+l*A.N[0]*A.N[1]]);
      printf("\n");
    }
    return(1);
  }
}

配列サンプル.cpp

#include <stdio.h>
#include <stdlib.h>

#include "Util.h"

int main(void) {

    Array<double> a;

    a.nDims = 2; a.N[0] = 2; a.N[1] = 2; a.size = 4;
    a.x = (double *)calloc(a.size,sizeof(double));
    a.x[0] = 1.23; a.x[1] = 2.23; a.x[2] = 3.23; a.x[3] = 5.23;

    printArray(a);

    Array<int>   b;
    b.nDims = 2; b.N[0] = 2; b.N[1] = 2; b.size = 4;
    b.x = (int *)calloc(b.size,sizeof(int));
    b.x[0] = 1; b.x[1] = 2; b.x[2] = 3; b.x[3] = 5;

    printArray(b);

        return 0;
}
4

2 に答える 2

0

あなたはすでにある意味であなた自身の質問に答えています。コードをカット アンド ペーストするか、util.h ファイルで #include ディレクティブを使用して、util.cpp コードを util.h ファイルと組み合わせる必要があります。次に、util.h ファイルを arraySample.cpp に #include すると、目的の効果が得られます。この説明と歴史については、Vandevorde と Josuttis による「C++ テンプレート」の第 6 章を参照してください。

于 2013-04-05T13:52:19.587 に答える
0

printArrayヘッダー ファイルでテンプレート関数を定義する必要があります。すべてを からUtil.cppに移動するだけUtil.hです。

このように考えてみてください。コンパイラがコンパイルしているときmain.cpp、それはasでテンプレートprintArray(a)をインスタンス化しようとします。ただし、関数の定義が表示されないため、対応するコードを生成できません。そのため、この時点で関数の実装をコンパイラから見えるようにするには、関数の実装をヘッダーに配置する必要があります。printArrayTdouble

まったく同じことを達成する代替手段は、(の上部ではなく)#include <Util.cpp>の下部にあります。ただし、代わりにテンプレート実装ファイルに拡張子を付けるのはかなり一般的な方法です。これにより、関係が少し明確になります。Util.h#include <Util.h>Util.cpp.tpp

于 2013-04-05T12:44:20.757 に答える