0

テンプレート クラスをコンパイルすると、未解決の外部コンパイル エラーが発生します。コードを .h ファイルと .cpp ファイルに分けました。

いくつかの投稿を読みましたが、この投稿で説明されているように、リンクの問題が原因でこれが機能しないことを理解しました。

  1. テンプレートのヘッダー ファイルにメンバー関数の完全な定義を含め、テンプレートのソース ファイルを持たない。

  2. テンプレートのソース ファイル内のすべてのメンバー関数を「インライン」として定義する、または

  3. 「エクスポート」キーワードを使用して、テンプレートのソースでメンバー関数を定義します。残念ながら、これは多くのコンパイラでサポートされていません。

ただし、これらの多くのテンプレート関数間の変換関数があるため、これらのオプションはどれも機能しません (クロス インクルード コンパイルの問題が発生します)。

この問題を解決するにはどうすればよいですか?

編集:コードを含める

StaticArray.h

template<typename T>
class Array;

template<typename T, unsigned int N>
class StaticArray
{
protected:
    T* _data[N];
public:
    StaticArray();
    StaticArray(const StaticArray<T,N>& other);
    ~StaticArray();

    void Release(unsigned int index);
    void Release(T* data);
    void ReleaseAll();

    Array<T> ToArray();

    bool operator == (const StaticArray<T,N>& other);
    bool operator != (const StaticArray<T,N>& other);
    T*& operator [] (unsigned int index) const;
    StaticArray<T,N>& operator = (const StaticArray<T,N>& other);
};

StaticArray.cpp

#pragma region StaticArray::CoreMethods

template<typename T, unsigned int N>
StaticArray<T, N>::StaticArray()
{
    for (unsigned int i = 0; i < N; i++)
    {
        this->_data[i] = null;
    }
}

template<typename T, unsigned int N>
StaticArray<T, N>::StaticArray(const StaticArray<T,N>& other)
{
    for (unsigned int i = 0; i < N; i++)
    {
        this->_data[i] = other._data[i];
    }
}

template<typename T, unsigned int N>
StaticArray<T, N>::~StaticArray()
{

}

#pragma endregion

#pragma region StaticArray::Methods

template<typename T, unsigned int N>
void StaticArray<T,N>::Release(unsigned int index)
{
    if (index < N)
    {
        delete this->_data[i];
        this->_data[i] = null;
    }
    else
    {
        throw new Exception::IndexOutOfBoundsException("StaticArray accessed at index greater than N.");
    }
}

template<typename T, unsigned int N>
void StaticArray<T,N>::Release(T* data)
{
    if (data == null)
    {
        throw new Exception::InvalidArgumentException("StaticArray Release call argument must not be null.");
    }

    for (unsigned int i = 0; i < N; i++)
    {
        if (this->_data[i] == data)
        {
            this->Release(i);
            return;
        }
    }

    throw new Exception::InvalidArgumentException("StaticArray Release call argument was not in the array.");
}

template<typename T, unsigned int N>
void StaticArray<T,N>::ReleaseAll()
{
    for (unsigned int i = 0; i < N; i++)
    {
        if (this->_data[i] != null)
        {
            delete this->_data[i];
            this->_data[i] = null;
        }
    }
}

template<typename T, unsigned int N>
Array<T> StaticArray<T,N>::ToArray()
{
    Array<T> ret(N);

    for (unsigned int i = 0; i < N; i++)
    {
        ret[i] = this->_data[i];
    }

    return ret;
}

#pragma endregion

#pragma region StaticArray::OperatorOverloads

template<typename T, unsigned int N>
bool StaticArray<T,N>::operator == (const StaticArray<T,N>& other)
{
    for (unsigned int i = 0; i < N; i++)
    {
        if (this->_data[i] != other._data[i])
        {
            return false;
        }
    }

    return true;
}

template<typename T, unsigned int N>
bool StaticArray<T,N>::operator != (const StaticArray<T,N>& other)
{
    return !((*this) == other);
}

template<typename T, unsigned int N>
T*& StaticArray<T, N>::operator[](unsigned int index) const
{
    if (index < N)
    {
        return this->_data[index];
    }
    else
    {
        throw new Exception::IndexOutOfBoundsException("StaticArray accessed at index greater than N.");
    }
}

template<typename T, unsigned int N>
StaticArray<T, N>& StaticArray<T, N>::operator = (const StaticArray<T,N>& other)
{
    for (unsigned int i = 0; i < N; i++)
    {
        this->_data[i] = other._data[i];
    }
    return *this;
}

main.cpp

#include "StaticArray.h"
#include "Array.h"

int main(int argc, char** argv[])
{
    StaticArray<int,5> sar;

    sar[0] = new int(1);
    sar[1] = new int(2);
    sar[2] = new int(3);
    sar[3] = new int(4);
    sar[4] = new int(5);

    return 0;
}
4

4 に答える 4

0

明示的なテンプレートのインスタンス化。次の行を StaticArray.cpp の最後に追加します。

template class StaticArray<int,5>;
于 2013-06-03T04:43:47.863 に答える
0

StaticArray.h の先頭にクラス Array の前方宣言があります。main.cpp で、行を次のように交換してみてください

#include "Array.h"
#include "StaticArray.h"

一見すると、コンパイラが StaticArray の構築時に Array を認識していないように見えるため、未解決の外部?

于 2013-06-03T04:44:49.573 に答える
0

実際に を呼び出す時点を除き、class Array使用するを定義する必要はありません。したがって、それぞれが使用するクラスを前方宣言する限り、テンプレートとその関数がどの順序で宣言されても問題ありません。class StaticArrayToArray

于 2013-06-03T13:21:49.723 に答える