Undefine reference do mojej funkcji w szablonie

0

Mam następujący program:

app.cpp:
[code]
#include "app.h"
#include "ortho.h"

using namespace myNam;

namespace myNam
{

app::app ()
{

}

app::~app()
{

}

int app::exec()
{
ublas::matrix<double> A(3,3);
ublas::matrix<double> Q(3,3);
ublas::matrix<double> R(3,3);

double tab[3][3] =
{
    {1, 2, 3}, {1, 2, 2}, {4, 1, 3}
};

for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
        A(i, j) = tab[i][j];

int x = 10;
QR_Ortho_Decomposition (A);
std::cout << "Hello world!" << std::endl;
return 0;

}

}

[/code]

ortho.h
[code]
#ifndef ORTHO
#define ORTHO

#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>

namespace ublas = boost::ublas;

namespace myNam
{

template <class S>
int QR_Ortho_Decomposition (ublas::matrix<S> A);

template <class S>
ublas::matrix<S> ortho_projection (ublas::matrix<S> e, ublas::matrix<S> a);

}

#endif ORTHO

[/code]

ortho.cpp
[code]
#include "ortho.h"

using namespace myNam;

namespace myNam
{

template <class S>
int QR_Ortho_Decomposition (ublas::matrix<S> A)
{
// const int n = A.size1();
// const int m = A.size2();

// vector<S> *v = new vector<S>[n];

// delete v;
return 0;
}

template <class S>
ublas::matrix<S> ortho_projection (ublas::matrix<S> e, ublas::matrix<S> a)
{
return inner_prod(e,a)/inner_prod(e,e)*e;
}

}

[/code]

To nie cały kod, ale ograniczyłem się do najważniejszej części

Gdy spróbowałem skompilować program wyświetla się mnie napis:
[quote]
obj/Debug/app.o||In function myNam::app::exec()':| /home/tomasz/Dokumenty/prace/c/numer_qr_sol_ortho/app.cpp|35|undefined reference to int myNam::QR_Ortho_Decomposition<int>(boost::matrix<int, boost::basic_row_major<unsigned int, int>, boost::unbounded_array<int, std::allocator<int> > >)'|
== Build finished: 1 errors, 0 warnings ===

[/quote]

Co robię źle? Dziwne, że codeblocks widzi odwołanie i wyświetla poprawnie auto uzupełnianie ;p

0

Tak na szybko to z komunikatu wydaje się, że kompilator jakoś sam zgadnął, że wartościami w macierzy to int'y, gdy oczekuje double (nie wiem czemu). Spróbuj te wartości w tab[] zapisać jako 1.0, 2.0 itd.

0

Nie możesz mieć definicji funkcji szablonowej w pliku cpp, ponieważ kompilator nie wie jak stworzyć te funkcje kiedy one są używane w innych plikach cpp (dokładnie chodzi mi o jednostki kompilacji). Najpopularniejszym rozwiązaniem jest zamieszczenie definicji funkcji w pliku h. Gdy zależy ci na szybkości kompilacji, to są na to inne rozwiązania, patrz google.

0

Nie możesz mieć definicji funkcji szablonowej w pliku cpp, ponieważ kompilator nie wie jak stworzyć te funkcje kiedy one są używane w innych plikach cpp

Nie jest to prawda. Kompilator nie potrafi automatycznie stworzyć specjalizacji funkcji szablonowej jeśli nie jest zdefiniowana w bieżącej jednostce kompilacji. Jeśli jednak występuje legalna specjalizacja (jawna bądź automatyczna) w jednostce, w której funkcja jest zdefiniowana, to linker taką funkcję znajdzie nawet jeśli jest użyta w innym pliku cpp.

w podanym przykładzie należałoby dodać do pliku ortho.cpp linijki:

template ublas::matrix<double> ortho_projection (ublas::matrix<double> e, ublas::matrix<double> a);
template int QR_Ortho_Decomposition (ublas::matrix<double> A);

i pójdzie gładko. niestety, tak trzeba by robić dla każdego typu którego chcemy użyć jako parametr szablonu, co może być uciążliwe.

1 użytkowników online, w tym zalogowanych: 0, gości: 1