Undefine reference do mojej funkcji w szablonie

Odpowiedz Nowy wątek
2011-10-05 22:11
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::numeric::ublas;

namespace myNam
{

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

template <class s="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="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="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 toint myNam::QR_Ortho_Decomposition<int>(boost::numeric::ublas::matrix<int, boost::numeric::ublas::basic_row_major<unsigned int, int>, boost::numeric::ublas::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


Software is like sex, It's better when it's free.

Pokochaj -Wall -Wextra -pedantic -g -pg
Kompilator i debugger to twoi najlepsi przyjaciele
edytowany 3x, ostatnio: tpsa, 2011-10-05 22:12

Pozostało 580 znaków

2011-10-05 23:41
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.

Pozostało 580 znaków

2011-10-06 03:04

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.

Pozostało 580 znaków

2011-10-06 10:39
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.

I generalnie jest bez sensu. Ale dobrze wiedzieć... - vpiotr 2011-10-06 12:33
Trochę uprościłem to w swojej wypowiedzi. Ogólnie taki sposób to koszmar, stosowanie takiej metody przy poważnym programowaniu z użyciem szablonów doprowadzi do kodu, którego nie ma jak zmienić (mówię o używaniu szablonów w stylu CGALa). - Zjarek 2011-10-06 14:41

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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