I have some code that looks like this in an Array.hpp
file
template <typename T>
class Array {
private:
T *_array;
int _arrSize;
public:
Array<T>();
Array<T>(unsigned int n);
...
};
then on the Array.cpp
file I have like this
#include "Array.hpp"
template <typename T>
Array<T>::Array<T>(){};
template <typename T>
Array<T>::Array<T>(unsigned int n) : _arrSize(n) {
T *a = new T[n];
for (unsigned int i = 0; i < n; i++) {
a[i] = 0;
}
this->_array = a;
};
...
then a main as simple as
int main() {
Array<int> g(2);
return 0;
}
but when I try to compile this with clang++ -Wall -Wextra -Werror -std=c++98 *.c
I get this error
Array.cpp:16:11: error: out-of-line constructor for 'Array' cannot have template arguments Array<T>::Array<T>(){}; ^ ~~~ Array.cpp:19:11: error: out-of-line constructor for 'Array' cannot have template arguments Array<T>::Array<T>(unsigned int n) : _arrSize(n) { ^ ~~~
I'm not sure what I'm doing wrong
your definitions prototype is wrong:
template <typename T>
Array<T>::Array<T>(){};
the Visual Studio 2015 compiler issues this warning that make the error a bit more clear:
warning C4812: obsolete declaration style: please use 'Array<T>::Array' instead
so your implementation should look like:
template <typename T>
Array<T>::Array(){};
template <typename T>
Array<T>::Array(unsigned int n) : _arrSize(n) {
...
};
...
This is because the constructor itself is not "templated".
If the declaration would look like.
template <typename T>
class Array<T>
{
template <typename Y>
Array<T>(Y n);
};
you would require this additional template argument, but with another template line:
template <typename T>
template <typename Y>
Array<T>::Array<Y>(Y n){};
However one more problem of your code is that you hide the template implementation from the the including files, so the compiler can not instantiate it.
Currently your main.cpp
is unable to see the constructor implementations. it only sees the declaration in the header.
You have different options:
Array.cpp
: with directives like:
template class Array<int>;
at file scope. For a container type this does not seem to be an option.Array.cpp
(but i would call it Array_Impl.hpp
at the end of your header (but you have to be careful, because everything in the cpp will be visible in the header and for all files that include your header)The correct syntax is
Array<T>::Array()
not
Array<T>::Array<T>()
On a related note, implementing your templates in .cpp files is almost always wrong.
You should be using std::vector
anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With