C ++ Unresolved External - 模板

时间:2013-06-03 04:02:04

标签: c++ templates unresolved-external

编译模板类时,我收到一个未解决的外部编译错误。我已将代码分成.h和.cpp文件。

我阅读了一些帖子,现在我知道由于this post中解释的链接问题,这不起作用。

  
      
  1. 在模板的头文件中包含成员函数的完整定义,并且没有模板的源文件,

  2.   
  3. 将模板源文件中的所有成员函数定义为“inline”,或

  4.   
  5. 使用“export”关键字定义模板源代码中的成员函数。不幸的是,许多编译器都不支持这一点。

  6.   

但是,这些选项都不起作用,因为我在许多这些模板函数之间都有转换函数(导致交叉包含编译问题)。

如何解决此问题?

编辑:包含代码

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 个答案:

答案 0 :(得分:0)

显式模板实例化。将此行添加到StaticArray.cpp的底部:

template class StaticArray<int,5>;

答案 1 :(得分:0)

我在StaticArray.h的开头看到了类Array的前向声明。在你的main.cpp中尝试将行交换到

#include "Array.h"
#include "StaticArray.h"
从快速浏览一下,编译器在构建StaticArray并因此无法解析外部时,似乎没有看到Array?

答案 2 :(得分:0)

我最终设法找出使这项功能以结构化方式运作的最佳方法。

您需要从StaticArray课程中删除转化(例如ArrayStaticArray),并将StaticArrayArray包括在另一个包含实用程序功能(例如转换)的代码文件。

这里的关键是保持包括向上工作。即:utility.h(例如)包括Array.h和StaticArray.h,而不是包括彼此。

然后您可以自由地将所有定义代码放入StaticArray.h文件中,而不会产生交叉包含的副作用(从而修复未解析的外部因素)。

答案 3 :(得分:0)

除了您实际呼叫class Array之外,您不必定义class StaticArray来使用ToArray。因此,模板及其函数的声明顺序无关紧要,只要每个模板及其函数都向前声明它所使用的类。