[Insight-users] Undefined reference to a templated function. Error in compilation.

Seth Gilchrist seth at mech.ubc.ca
Thu Mar 10 19:14:22 EST 2011


Hi all,
I am getting the following error when compiling my program:

    CMakeFiles/TestProgram.dir/TestProgram.cxx.o: In function `main':
    TestProgram.cxx:(.text+0x18a): undefined reference to
`DICMesh<itk::Image<short, 3u>, itk::Image<short, 3u>,
itk::Mesh<itk::Vector<double, 4u>, 3u,
itk::DefaultStaticMeshTraits<itk::Vector<double, 4u>, 3u, 3u, float, float,
itk::Vector<double, 4u> > > >::DICMesh()'
    collect2: ld returned 1 exit status
    make[2]: *** [TestProgram] Error 1
    make[1]: *** [CMakeFiles/TestProgram.dir/all] Error 2
    make: *** [all] Error 2

The problem is with instantiation of a templated class.  The class is called
DICMesh and inherits a bunch of stuff from a class called DIC.
TestProgram.cxx and the (truncated) DIC and DICMesh hxx/cxx files containing
the constructors are below.  There seems to be something about having to use
"export" (which I'm not very familiar with) or maybe #include'ing the cxx
file in the hxx file (from here:
http://bytes.com/topic/c/answers/128614-undefined-reference-template-class)
but none of this is reflected in any textbooks that I have referenced.

Does anybody have a recommendation or a reference that I could look at to
solve this?  I am newish to C++ (only ever programed main functions to this
point) so you may see lots of yet unidentified errors as I can't even start
the de-bugging until I get this solved.

Thanks,
Seth
ubuntu 10.10 64bit
ITK 3.20 (Paul Novo's build 3.20.0-novo 1)
VTK 5.4 (5.4.2-7ubuntu3)
gcc 4:4.4.4-1ubuntu2
g++ 4:4.4.4-1ubuntu2
cmake 2.8.3-1~maverick1


################## TestProgram.cxx #########

#include <iostream>
#include "DIC.hxx"
#include "DICMesh.hxx"

int main(int argc, char **argv)
{
    // create the images
    typedef    short            ImagePixelType;
    const unsigned int    dimension = 3;
    typedef itk::Image< ImagePixelType, dimension >        FixedImageType;
    typedef    itk::Image< ImagePixelType, dimension >
MovingImageType;

    typedef    double            MeshPixelComponentType;
    typedef    itk::Vector< MeshPixelComponentType,4 >        MeshPixelType;
    typedef itk::Mesh< MeshPixelType, dimension >        MeshType;
    MeshType::Pointer    mesh = MeshType::New(); // the mesh to be filled
with the points

    // create the image readers
    typedef itk::ImageFileReader< FixedImageType >
FixedImageReaderType;
    typedef    itk::ImageFileReader< MovingImageType >
MovingImageReaderType;

    FixedImageReaderType::Pointer    fixedReader =
FixedImageReaderType::New();
    MovingImageReaderType::Pointer    movingReader =
MovingImageReaderType::New();

    fixedReader->SetFileName( argv[1] );
    movingReader->SetFileName( argv[2] );

    try
    {
        fixedReader->Update();
        movingReader->Update();
    }
    catch( itk::ExceptionObject & err )
    {
        std::cerr<<"Error updating fixed and moving readers"<<std::endl;
        std::cerr<<"Message:"<<std::endl;
        std::cerr<<err<<std::endl<<std::endl;
        return EXIT_FAILURE;
    }

    // test creating a DICMesh filter
    DICMesh<FixedImageType,MovingImageType,MeshType>     DICMethod;

    std::cout<<"DICMethod created."<<std::endl;


    return 0;
}

######### DIC.hxx ############

#ifndef DIC_H
#define DIC_H

#include <iostream>
#include <vector>
#include "itkImage.h"
#include "itkVector.h"
#include "itkRegionOfInterestImageFilter.h"
#include "itkImageRegistrationMethod.h"
#include "itkMeanSquaresImageToImageMetric.h" // default metric
#include "itkRegularStepGradientDescentOptimizer.h" // default optimizer
#include "itkTranslationTransform.h" // default transform
#include "itkLinearInterpolateImageFunction.h" // default interpolator
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

template <typename TFixedImage, typename TMovingImage>
class DIC
{
public:
    /** Types  and member functions**/

protected:
    DIC();
    ~DIC() {}

private:
    /** unititalized private variables. **/

}; // end class DIC

#endif // DIC_H

########### DIC.cxx ############

#include "DIC.hxx"

template <typename TFixedImage, typename TMovingImage>
DIC<TFixedImage,TMovingImage>
::DIC()
{
    m_FixedImage = 0; // must be provided by user
    m_MovingImage = 0; // must be provided by user
    m_IRRadius = 0; // must be provided by user

    /** Setup the default registration method.*/
    m_Registration = ImageRegistrationMethodType::New();
    m_Metric = itk::MeanSquaresImageToImageMetric< TFixedImage,
TMovingImage>::New();
    m_Optimizer = itk::RegularStepGradientDescentOptimizer::New();
    m_Transform = itk::TranslationTransform< double,
FixedImageType::ImageDimension >::New();
    m_Interpolator = itk::LinearInterpolateImageFunction< TFixedImage,
double >::New();
    m_Registration->SetMetric(m_Metric);
    m_Registration->SetOptimizer(m_Optimizer);
    m_Registration->SetTransform(m_Transform);
    m_Registration->SetInterpolator(m_Interpolator);

    m_CurrentFixedImage = 0;
    m_CurrentMovingImage = 0;

    UseWholeMovingImage = false;
    m_MovingIRMult = 3; // default size of the moving IR is 3 times the size
of the fixed IR
    m_CurrentFixedImage = 0;
    m_FixedImageRegionList = 0;
    m_MovingImageRegionList = 0;
}

/** All those other members. **/

############## DICMesh.hxx #############

#ifndef DICMESH_H
#define DICMESH_H

#include <iostream>
#include <fstream>
#include <cstring>
#include "DIC.hxx"
#include "itkMesh.h"

template<typename TFixedImage, typename TMovingImage, typename TMeshType>
class DICMesh : public DIC<TFixedImage, TMovingImage>
{
public:

    /** Typedefs for DICMesh*/

    /** Inherited typedefs from DIC.*/

    /*...A bunch of member functions that are never called in
TestProgram.cxx...*/

    DICMesh();
    ~DICMesh() {}

private:
    /** unititalized private variables. **/

}; // end class DICMesh

#endif // DICMESH_H

############### DICMesh.cxx ############

#include "DICMesh.hxx"

template<typename TFixedImage, typename TMovingImage, typename TMeshType>
DICMesh<TFixedImage, TMovingImage, TMeshType>
::DICMesh()
{
    m_OutputImage = 0; // must be provided by user
    m_InitialDataImage = 0; // must be provided by user
}

/** Other members **/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20110310/cc3ae70a/attachment.htm>


More information about the Insight-users mailing list