Question

I am in main, and am trying to pass an Eigen object to a function located in a different class. I am able to make this function call without a problem when both functions are in the same file. See my sample code for my problem. It does not link. What is the problem, and how can I fix it?

The makers of Eigen, eigen.tuxfamily.org, talk about how to pass eigen objects to functions. Unfortunately, I have not been able to expand their example past a single file.

How to pass an object:

http://eigen.tuxfamily.org/api/TopicPassingByValue.html

How to pass an object with expression templates:

http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html

main.cpp

#include <cstdlib>
#include <iostream>
#include <Eigen>
#include "MatrixMathTester.h"
using namespace std;
using namespace Eigen;

int main(int argc, char** argv)
{
    MatrixMathTester matrixMathObject;

    MatrixXd outputMatrix(2, 2);
    outputMatrix << 22, 11, 22, 11;

    matrixMathObject.internalMatrixMath(outputMatrix);

    return 0;
}

MatrixMathTester.h:

#ifndef MATRIXMATHTESTER_H
#define MATRIXMATHTESTER_H

#include <iostream>
#include <Eigen>
using namespace Eigen;

class MatrixMathTester {
public:
    MatrixMathTester();
    MatrixMathTester(const MatrixMathTester& orig);
    virtual ~MatrixMathTester(); 

    template <typename Derived>
    void internalMatrixMath(const MatrixBase<Derived>& inputMatrix);
};
#endif /* MATRIXMATHTESTER_H */

MatrixMathTester.cpp:

#include "MatrixMathTester.h"
using namespace std;
using namespace Eigen;

MatrixMathTester::MatrixMathTester(){}
MatrixMathTester::MatrixMathTester(const MatrixMathTester& orig){}
MatrixMathTester::~MatrixMathTester(){}

template <typename Derived>
void MatrixMathTester::internalMatrixMath(const MatrixBase<Derived>& inputMatrix)
{
cout << "InputMatrix" << endl << inputMatrix << endl;
}

Error

"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
"/usr/bin/make"  -f nbproject/Makefile-Debug.mk dist/Debug/GNU-MacOSX/testinggrounds
mkdir -p build/Debug/GNU-MacOSX
rm -f build/Debug/GNU-MacOSX/main.o.d
g++ -I/Users/folder/Documents/CPP_Librarys/eigen/Eigen   -c -g \
    -I../../../CPP_Library/eigen/Eigen -MMD -MP -MF 
    build/Debug/GNU-MacOSX/main.o.d -o build/Debug/GNU-MacOSX/main.o main.cpp
mkdir -p build/Debug/GNU-MacOSX
rm -f build/Debug/GNU-MacOSX/MatrixMathTester.o.d
g++ -I/Users/folder/Documents/CPP_Librarys/eigen/Eigen   -c -g -MMD -MP \
    -MF build/Debug/GNU-MacOSX/MatrixMathTester.o.d -o \
    build/Debug/GNU-MacOSX/MatrixMathTester.o MatrixMathTester.cpp
mkdir -p dist/Debug/GNU-MacOSX
g++ -I/Users/folder/Documents/CPP_Librarys/eigen/Eigen    -o \
    dist/Debug/GNU-MacOSX/testinggrounds build/Debug/GNU-MacOSX/main.o \
    build/Debug/GNU-MacOSX/MatrixMathTester.o  
Undefined symbols:
  "void MatrixMathTester::internalMatrixMath<Eigen::Matrix<double, -1, -1, 0, -1, -1>
   >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&)",
referenced from:
  _main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Was it helpful?

Solution

Unfortunately you can't put the definition of your template member function in MatrixMathTester.cpp. When the compiler sees that file it doesn't know what instantiations you're going to want elsething, so it doesn't generate the one you need.

If you move the definition to MatrixMathTester.h then all will be well. When compiling main.cpp the compiler will then see the body of the template and the instantiation you need and will do the right thing.

OTHER TIPS

The following implements the solution. This code has been tested and works.

MatrixMathTester.h:

#ifndef MATRIXMATHTESTER_H
#define MATRIXMATHTESTER_H

#include <iostream>
#include <Eigen>
using namespace Eigen;
using namespace std;

class MatrixMathTester {
public:
    MatrixMathTester();
    MatrixMathTester(const MatrixMathTester& orig);
    virtual ~MatrixMathTester();

    template <typename Derived>
    void internalMatrixMath(const MatrixBase<Derived>& inputMatrix) 
    {
        cout << "InputMatrix" << endl << inputMatrix << endl;
    }
};
#endif  /* MATRIXMATHTESTER_H */

MatrixMathTester.cpp:

#include "MatrixMathTester.h"
using namespace std;
using namespace Eigen;

MatrixMathTester::MatrixMathTester(){}
MatrixMathTester::MatrixMathTester(const MatrixMathTester& orig){}
MatrixMathTester::~MatrixMathTester(){}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top