явный пример создания шаблона класса c ++ на macos, не работает на ubuntu

0

Я пишу код, который я хочу опубликовать как.h файлы и статическую библиотеку. Код написан с использованием шаблона c++ с объявлением класса в файле.h, а определение - в.cpp файле. Я использовал трюк "явного инстанцирования", чтобы сделать компиляцию кода в статическую библиотеку. Явное инстанцирование добавляется в конец.cpp файла. Я написал код для тестирования этой библиотеки. Он отлично работает на macos и windows, но на ubuntu он возвращает ошибку "неопределенной ссылки". Кажется, что трюк "явного инстанцирования" не работает на ubuntu. Кто-нибудь знает, почему?

Версия g++ на ubuntu - 4.5.3.

редактировать

Это файл.h файла шаблона:

#ifndef PHYSIKA_CORE_MATRICES_MATRIX_2X2_H_
#define PHYSIKA_CORE_MATRICES_MATRIX_2X2_H_

#include "Physika_Core/Utilities/global_config.h"
#include "Physika_Core/Matrices/matrix_base.h"

namespace Physika{

template <typename Scalar>
class Matrix2x2: public MatrixBase<Scalar,2,2>
{
public:
Matrix2x2();
Matrix2x2(Scalar x00, Scalar x01, Scalar x10, Scalar x11);
~Matrix2x2();
inline int rows() const{return 2;}
inline int cols() const{return 2;}
Scalar& operator() (int i, int j);
const Scalar& operator() (int i, int j) const;
Matrix2x2<Scalar> operator+ (const Matrix2x2<Scalar> &) const;
//other operation declarations
//omitted here
};

//overriding << for Matrix2x2
template <typename Scalar>
std::ostream& operator<< (std::ostream &s, const Matrix2x2<Scalar> &mat)
{
  s<<mat(0,0)<<", "<<mat(0,1)<<std::endl;
  s<<mat(1,0)<<", "<<mat(1,1)<<std::endl;
  return s;
}

}  //end of namespace Physika

#endif //PHYSIKA_CORE_MATRICES_MATRIX_2X2_H_

Файл.cpp для класса шаблонов выглядит следующим образом:

#include "Physika_Core/Matrices/matrix_2x2.h"

namespace Physika{

template <typename Scalar>
Matrix2x2<Scalar>::Matrix2x2()
{
}

template <typename Scalar>
Matrix2x2<Scalar>::Matrix2x2(Scalar x00, Scalar x01, Scalar x10, Scalar x11)
{
#ifdef PHYSIKA_USE_EIGEN_MATRIX
  eigen_matrix_2x2_(0,0) = x00;
  eigen_matrix_2x2_(0,1) = x01;
  eigen_matrix_2x2_(1,0) = x10;
  eigen_matrix_2x2_(1,1) = x11;
#endif
}

//other operation definitions
//omitted here

//explicit instantiation of template so that it could be compiled into a lib
template class Matrix2x2<float>;
template class Matrix2x2<double>;

}  //end of namespace Physika

Код теста выглядит так:

#include <iostream>
#include "Physika_Core/Matrices/matrix_2x2.h"
using namespace std;
using Physika::Matrix2x2;

int main()
{
  cout<<"Matrix2x2 Test"<<endl;
  Matrix2x2<double> mat_double(2.0,1.0,1.0,2.0);
  cout<<"A 2x2 matrix of double numbers:"<<endl;
  cout<<mat_double;
  return 0;
}

Информация об ошибке:

g++ -Wall -Wno-write-strings -O2 -I ../../Public_Library/include -L ../../Public_Library/lib -l matrices matrix2x2_test.cpp -o matrix2x2_test
/tmp/ccUrtwwf.o: In function 'main':
matrix2x2_test.cpp:(.text+0x91): undefined reference to 'Physika::Matrix2x2<double>::Matrix2x2(double, double, double, double)'
matrix2x2_test.cpp:(.text+0x1b9): undefined reference to 'Physika::Matrix2x2<double>::Matrix2x2(double, double, double, double)'
//more moitted here
collect2: ld returned 1 exit status
make: *** [matrix2x2_test] Error 1
Теги:
explicit-instantiation

1 ответ

0
Лучший ответ

Я решил эту проблему, заменив команду компиляции

g++ -Wall -Wno-write-strings -O2 -I ../../Public_Library/include -L ../../Public_Library/lib -l matrices matrix2x2_test.cpp -o matrix2x2_test

с:

g++ matrix2x2_test.cpp -o matrix2x2_test -Wall -Wno-write-strings -O2 -I ../../Public_Library/include -L ../../Public_Library/lib -l matrices

Это так странно, что я только что переместил "matrix2x2_test.cpp -o matrix2x2_test" вперед. Во всяком случае, проблема решена.

  • 0
    рад, что вы решили свою проблему, не могли бы вы поделиться своими рабочими командами компиляции из MacOS и Windows? Ошибка совсем не странная, и мне довольно любопытно, почему она сработала в таких случаях.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню