0

テンプレート化されたクラスを次のように使用したいというかなり標準的な状況があります。

  1. .h ファイルを定義する
  2. .cpp を含める

私が試した他のすべてのコンパイラ (つまり、g++ と clang/llvm) では、これは正常に動作します。Visual Studio では、ファイルが既に定義されていることがわかります。

テキストを .cpp から .h ファイルに手動でカット アンド ペーストすると、すべて問題なく動作します。それがまさに#includeやるべきことだという印象を受けました。

私の推測では、Visual Studio が何らかの方法で .cpp ファイルを複数回コンパイルしているということです (ただし#pragma once、.h および .cpp ファイルに配置しました)。

何が起こっているのですか? テンプレート クラスを VS で動作させるにはどうすればよいですか?

コードは次のとおりです:
.h:

#pragma once
template <class T>
class myVector
{
private:
    void grow();
public:
int size;
int index;
T** words;
void pushBack(T* data);
inline T* operator[](int);
myVector(void);
~myVector(void);
};

#include "myVector.cpp"

.cpp:

#pragma once
#include "stdafx.h"
#include <cstdlib>
#include "myVector.h"
#include <iostream>
using namespace std;

template<class T>
myVector<T>::myVector(void)
{
    this->size = 2000;
    words = new T*[size];
    index=0;
}

template<class T>
void myVector<T>::pushBack(T* input)
{
    if(index<size)
    {
        words[index]=input;
    }
    else
    {
        grow();
        words[index]=input;
    }
    index++;
}

template<class T>
T* myVector<T>::operator[](int i)
{
    return words[i];
}

template<class T>
void myVector<T>::grow()
{
    //cout<<"I grew:"<<endl;
    size*=2;
    words = (T**)realloc(words,size*sizeof(T*));
}

template<class T>
myVector<T>::~myVector(void)
{
    delete[] words;
}    
4

1 に答える 1

2

あなたの混乱は#pragma once、翻訳ユニットがどのように機能するかを知らないことから生じているように私には思えます。

#pragma once、インクルードガードと同様に、ファイルの内容(通常はヘッダー)が単一の変換ユニットに複数回プルされるのを防ぎます。

複数の実装ファイルを使用している場合#include <vector>、コンテンツはすべてのファイルに取り込まれますが、翻訳単位ごとに1回だけです。

したがって#include "myVector.cpp"、MSVSは実装ファイルを自動的にコンパイルするため、を削除する必要があります。これも間違っています。

テンプレート定義を表示する必要があることに注意してください。そのため、テンプレート定義を.hファイルに移動するか、現在のアプローチを使用して、.cppファイルの名前を「.implまたは」に変更して.h含める必要があります。

于 2012-05-07T07:13:40.607 に答える