I am experiencing an undefined reference error, when compiling the following code using GCC 4.7.2 20130108 under x86_64-suse-linux via the command:
g++ main.cpp func.cpp -I/path/to/eigenlibrary/eigen_3.2.1
The error message reads:
main.cpp:(.text+0x1d): undefined reference to `void f<2>(std::vector<Eigen::Matrix<double, 2, 2,
((Eigen::._84)0)|((((2)==(1))&&((2)!=(1)))?
((Eigen::._84)1) : ((((2)==(1))&&((2)!=(1)))?((Eigen::._84)0) : ((Eigen::._84)0))), 2, 2>,
std::allocator<Eigen::Matrix<double, 2, 2, ((Eigen::._84)0)|((((2)==(1))&&((2)!=(1)))?
((Eigen::._84)1) : ((((2)==(1))&&((2)!=(1)))?((Eigen::._84)0) : ((Eigen::._84)0))), 2, 2> > >&)'
Please note that this has nothing to do with the fact that the template implementation is separated from the header file, because there is no (generic) implementation of the template function, but only a template specialization. The implementation of the template specialization can not be put into the header file, because this yields multiple definition errors.
Another strange thing here is that if I change the order of the first two header inclusions in main.cpp (Eigen/Dense and vector) the error does not occur. I have no understanding for this and any help that goes beyond 'simply change the order of the header inclusions then' would be highly appreciated.
main.cpp:
#include <vector>
#include <Eigen/Dense>
//error does not occur once I change order of header inclusion like so:
//#include <Eigen/Dense>
//#include <vector>
#include "func.h"
int main() {
std::vector<Eigen::Matrix<double, 2, 2> > m;
f<2>(m);
}
func.h
#ifndef FUNC_H
#define FUNC_H
#include <Eigen/Dense>
#include <vector>
template <int N>
void f(std::vector<Eigen::Matrix<double, N, N> >& m);
template <> void f<2>(std::vector<Eigen::Matrix<double, 2, 2> >& m);
#endif
func.cpp
#include "func.h"
#include <vector>
template <>
void f<2>(std::vector<Eigen::Matrix<double, 2, 2> >& m) {}