I just introduced templates into my classes and getting the following linker error (on linux):
Linking CXX executable main
CMakeFiles/main.dir/main.cc.o: In function `main':
/media/sf_Eclipse_Deal_II_sharedFolder/Eclipse_Win_workspace/ChannelFlowWithFlatPlateSource/main.cc:46: undefined reference to `ChannelFlow<dealii::Vector<double>, dealii::SparseMatrix<double> >::ChannelFlow(cmdParametersStruct)'
/media/sf_Eclipse_Deal_II_sharedFolder/Eclipse_Win_workspace/ChannelFlowWithFlatPlateSource/main.cc:48: undefined reference to `ChannelFlow<dealii::Vector<double>, dealii::SparseMatrix<double> >::run()'
CMakeFiles/main.dir/main.cc.o: In function `ChannelFlow<dealii::Vector<double>, dealii::SparseMatrix<double> >::~ChannelFlow()':
/media/sf_Eclipse_Deal_II_sharedFolder/Eclipse_Win_workspace/ChannelFlowWithFlatPlateSource/src/ChannelFlow.h:29: undefined reference to `BaseSolver<dealii::Vector<double>, dealii::SparseMatrix<double> >::~BaseSolver()'
CMakeFiles/main.dir/main.cc.o: In function `~ChannelFlow':
/media/sf_Eclipse_Deal_II_sharedFolder/Eclipse_Win_workspace/ChannelFlowWithFlatPlateSource/src/ChannelFlow.h:29: undefined reference to `BaseSolver<dealii::Vector<double>, dealii::SparseMatrix<double> >::~BaseSolver()'
collect2: error: ld returned 1 exit status
the only code from main.cc that uses ChannelFlow:
ChannelFlow<MyVectorType, SparseMatrixType> channelFlowProblem(cmdParameters);
channelFlowProblem.run();
Before templates it was linking and running well.
ChannelFlow.h file:
template <class VectorType, class SparseMatrixT>
class ChannelFlow : public BaseSolver<VectorType, SparseMatrixT>
{
Thank you! I added template class instantiation to the end of cpp files. The linker still gives errors I think because I also have template methods inside same template classes:
1 2 3 4 5 6 7
[ 66%] Building CXX object CMakeFiles/main.dir/src/one_pass_logic/doTimeStepOneRunAver.cpp.o
Linking CXX executable main
CMakeFiles/main.dir/src/one_pass_logic/doTimeStepOneRunAver.cpp.o: In function `ChannelFlow<dealii::TrilinosWrappers::MPI::Vector, dealii::TrilinosWrappers::SparseMatrix>::doTimeStepOneRunAver()':
/media/sf_Eclipse_Deal_II_sharedFolder/Eclipse_Win_workspace/ChannelFlowWithFlatPlateSource/src/one_pass_logic/doTimeStepOneRunAver.cpp:57: undefined reference to `Drag<dealii::Vector<double>, dealii::SparseMatrix<double> >::Drag<dealii::TrilinosWrappers::MPI::Vector, dealii::TrilinosWrappers::SparseMatrix>(ChannelFlow<dealii::TrilinosWrappers::MPI::Vector, dealii::TrilinosWrappers::SparseMatrix>&, cmdParametersStruct)'
/media/sf_Eclipse_Deal_II_sharedFolder/Eclipse_Win_workspace/ChannelFlowWithFlatPlateSource/src/one_pass_logic/doTimeStepOneRunAver.cpp:104: undefined reference to `double Drag<dealii::Vector<double>, dealii::SparseMatrix<double> >::computeDrag<dealii::TrilinosWrappers::MPI::Vector>(dealii::TrilinosWrappers::MPI::Vector&, dealii::TrilinosWrappers::MPI::Vector&)'
collect2: error: ld returned 1 exit status
make[6]: *** [main] Error 1
When I add template method instanciation like this :
/media/sf_Eclipse_Deal_II_sharedFolder/Eclipse_Win_workspace/ChannelFlowWithFlatPlateSource/src/drag/Drag.cpp:223:17: error: template-id �computeDrag<dealii::Vector<double> >’ for �double Drag<dealii::Vector<double>, dealii::SparseMatrix<double> >::computeDrag(dealii::Vector<double>, dealii::Vector<double>)’ does not match any template declaration
templatedouble Drag<dealii::Vector<double>, dealii::SparseMatrix<double>>::computeDrag<dealii::Vector<double>>( dealii::Vector<double>, dealii::Vector<double>);
^
/media/sf_Eclipse_Deal_II_sharedFolder/Eclipse_Win_workspace/ChannelFlowWithFlatPlateSource/src/drag/Drag.cpp:225:10: error: template-id �Drag<>’ for �Drag<dealii::Vector<double>, dealii::SparseMatrix<double> >::Drag(TrilVec, TrilMatrix, cmdParametersStruct)’ does not match any template declaration
template Drag<dealVector, dealMatr >::Drag(TrilVec, TrilMatrix, cmdParametersStruct);
^
/media/sf_Eclipse_Deal_II_sharedFolder/Eclipse_Win_workspace/ChannelFlowWithFlatPlateSource/src/drag/Drag.cpp:226:10: error: template-id �Drag<>’ for �Drag<dealii::Vector<double>, dealii::SparseMatrix<double> >::Drag(dealVector, dealMatr, cmdParametersStruct)’ does not match any template declaration
template Drag<dealVector, dealMatr >::Drag(dealVector, dealMatr, cmdParametersStruct);
^
Thank you for your help, but I really don't have time to write a testcase as I am under strict time deadline. I believe any code with template class containing template method (just put its implementation into separate file from class definition and don't include implementation file in header file or anywhere else) will give the above error.
I resolved it by putting all the implementation for the above class from cpp to header file. Don't like such solution.
So the question is still there: how to instantiate a template method of template class?
Is it possible at all?
So you need instantiate only template method?
I was instantiating template class itself as well. How to instantiate if you have 2 or more template methods?
instantiating the template class will generate the code for all non-template methods.
apart you'll need to instantiate each template method for every type that you want to use.