Question

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?

Was it helpful?

Solution

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:

  1. Move template operator= definition to .h, so compiler will be able to instantiate it at the place of call
  2. Provide explicit instantiations for template operator= 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top