I've a general problem with my application. I want to use lazy initialization with an Array class I've made, to improve performances; all works fine when all code is in a single *.h file, but compiler returns a linker error when I split the code in *.h*.cpp files. In the header file I have a
template <class T>
class simpleArray { ... some methods\operators declarations. ... }
and
template <typename T, typename derType=simpleArray<T>>
class myArray{.... some methods\operators declarations. ... }
and I've the explicit declaration of:
template class myArray<double>;
template class myArray<int>;
template class simpleArray<double>;
template class simpleArray<int>;
In the *.cpp file I've the implementation of methods and operators. Particularly I have two assignments operators:
template <class T, class derType>
myArray<T,derType>& myArray<T,derType>::operator= (myArray<T,derType> const& right)
{... some code ...}
template<class T, class derType>
template <class T2, class R2>
myArray<T,derType>& myArray<T,derType>::operator= (myArray<T2,R2> const& right)
{ ... some code ...}
The first one works fine, the second one (Arra=Array) returns the following errors:
Error 70 error LNK1120: 1 unresolved externals
Error 69 error LNK2019: unresolved external symbol "public: class myArray <double,class simpleArray<double> > & __thiscall myArray <double,class simpleArray<double> >::operator=<int,class simpleArray<int> >(class myArray <int,class simpleArray<int> > const &)"
May you please suggest some solutions? Do I have to include all code in the same file? I hope have been clear. Thank you for the support!
Ps. are there some "best practice" documents about code organization when using template?
The problem raised because you've placed template operator=
definition in .cpp
file:
template <class T, class derType>
template <class T2, class R2>
myArray<T,derType>& myArray<T,derType>::operator=(myArray<T2,R2> const& right)
{ ... }
Explicit instantiation that you are using works fine with regular function members of template class, but it doesn't with template function members of template class.
Just because in explicit instatiation directive you provide only actual T
and derType
types which are class template parameters, but not T2
and R2
which are function template parameters.
Possible solutions:
operator=
definition to .h
, so compiler will be able to instantiate it at the place of calloperator=
with all possible combinations of T
/derType
and T2
/R2
:Sample:
// Explicit instantiation of template classes
template class myArray<double>;
template class myArray<int>;
template class simpleArray<double>;
template class simpleArray<int>;
// Explicit instantiation of template members
template myArray<double>& myArray<double>::operator=(myArray<int> const&);
template myArray<int>& myArray<int>::operator=(myArray<double> const&);
P.S. The best template guide is still C++ Templates. The Complete Guide by David Vandevoorde and Nicolai M. Josuttis. It doesn't cover the new C++11 features yet, but the basics and most advanced topics are still actual.