3

これはとても簡単に思えますが、何が問題なのかわかりません。C++ ベクトル クラス (テンプレートではなく int のみ) を実装していますが、イテレータ テンプレートまたは typedef を含む関数をコンパイルすると、次のエラーが発生します。

Undefined symbols:
  "void vectorInt::assign<int>(int, int)", referenced from:
      _main in ccNVdR23.o
  "void vectorInt::assign<int*>(int*, int*)", referenced from:
      _main in ccNVdR23.o
      _main in ccNVdR23.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

ソース ファイルの重要な部分は次のとおりです。

vectorInt.h

#include <cstdlib>
#include <stdexcept>

typedef unsigned int size_type;

class vectorInt {
private:
    int* array;
    size_type current_size;
    size_type current_capacity;
public:
    .
    .
    .
    template <class InputIterator>
        void assign(InputIterator first, InputIterator last);
    void assign(size_type n, const int u);
};

#endif // VECTORINT_H

vectorInt.cpp

#include vectorInt.h
.
.
.
template <class InputIterator>
void vectorInt::assign(InputIterator first, InputIterator last) {
    clear();
    InputIterator it = first;
    int count = 0;
    while(it++ != last) {
        count++;
    }

    reserve(count);
    while(first != last) {
        this->push_back(*first++);
    }
}

void vectorInt::assign(size_type n, const int u) {
    clear();
    reserve(n);

    for(int i=0; i<(int)n; i++)
        push_back(u);
}

main.cpp

#include <cstdlib>
#include <stdexcept>
#include <iostream>
#include "vectorInt.h"

using namespace std;

int main(int argc, char** argv) {
    vectorInt first;
    vectorInt second;
    vectorInt third;

    first.assign(7, 100);

    vectorInt::iterator it;
    it = first.begin()+1;
    second.assign(it, first.end()-1); // the 5 central values of first

    int myints[] = {1776,7,4};
    third.assign(myints, myints+3);   // assigning from array.  

    return 0;
}

参考までに: main メソッドが vectorInt::iterator を使用していることは知っていますが、それは問題ではないため、ソース コードには含めませんでした。

4

2 に答える 2

3

割り当て関数のコードをヘッダー ファイル (vectorint.h) に配置すれば、問題ありません。テンプレートのコードは、代入関数を呼び出す場合に、インスタンス化されたときに表示される必要があります。

于 2012-02-13T17:06:13.473 に答える
3

テンプレート コードは2段階でコンパイルされます。フェーズ 1 には、基本的な構文チェックのみが含まれます。型Tに依存する 2 番目のフェーズは、コンパイラから完全なコンパイルを取得します。クラス/関数は type に基づいてインスタンス化されT、2 番目のフェーズのコンパイルはその型に対して実行されます。

コード (実装) は.cppファイル内にあるため、最初のフェーズのコンパイルのみが取得されるため、翻訳単位には含まれません。オブジェクト ファイルは生成されません。

テンプレートの場合、コンパイラがコード全体をコンパイルできるようにする必要があります。同じために、実装全体をヘッダーファイルのみに配置する必要があります。クラス宣言の直後にそれぞれのファイルを#includeすることもできます。.cpp

于 2012-02-13T17:08:15.250 に答える