编译模板类时,我收到一个未解决的外部编译错误。我已将代码分成.h和.cpp文件。
我阅读了一些帖子,现在我知道由于this post中解释的链接问题,这不起作用。
在模板的头文件中包含成员函数的完整定义,并且没有模板的源文件,
将模板源文件中的所有成员函数定义为“inline”,或
- 醇>
使用“export”关键字定义模板源代码中的成员函数。不幸的是,许多编译器都不支持这一点。
但是,这些选项都不起作用,因为我在许多这些模板函数之间都有转换函数(导致交叉包含编译问题)。
如何解决此问题?
编辑:包含代码
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;
}
答案 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
课程中删除转化(例如Array
至StaticArray
),并将StaticArray
和Array
包括在另一个包含实用程序功能(例如转换)的代码文件。
这里的关键是保持包括向上工作。即:utility.h(例如)包括Array.h和StaticArray.h,而不是包括彼此。
然后您可以自由地将所有定义代码放入StaticArray.h文件中,而不会产生交叉包含的副作用(从而修复未解析的外部因素)。
答案 3 :(得分:0)
除了您实际呼叫class Array
之外,您不必定义class StaticArray
来使用ToArray
。因此,模板及其函数的声明顺序无关紧要,只要每个模板及其函数都向前声明它所使用的类。