Błąd kompilacji prostej klasy szablonowej

0

Kompilacja dalej przedstawionego kodu kończy się błędem:
Error 1 error LNK2019: unresolved external symbol "public: double __thiscall Average<double>::Arithmetical(class std::vector<double,class std::allocator<double> >)" (?Arithmetical@?$Average@N@@QAENV?$vector@NV?$allocator@N@std@@@std@@@Z) referenced in function _main

Average.h

#ifndef Average.h
#define Average.h

#include "Core.h"

template <class T>
class Average
{
 public:
	Average() {}
	~Average() {}
	T Arithmetical(vector<T> a);
	T Geometric(vector<T> a);
	T Weighted(vector<T> a, vector<T> w);
};

#endif

Average.cpp

#include "Average.h"

template <class T>
T Average<T>::Arithmetical(vector<T> a)
{
	T result = accumulate(a.begin(),a.end(),0) / a.size();
	return result;
}

template <class T>
T Average<T>::Geometric(vector<T> a)
{
	T product;
	auto operation = [](T element) -> T { product*= element };
	for_each(a.begin(),a.end(), operation);
	T result = pow(product,-a.size());
	return result;
}

template <class T>
T Average<T>::Weighted(vector<T> a, vector<T> w)
{
	T magnitudeSum = 0;
	T result = 0;
	for(unsigned int i=0;i<a.size();++i)
	{
		magnitudeSum = magnitudeSum + a[i]*w[i];
	}
	result = magnitudeSum / accumulate(w.begin(),w.end(),0);
	return result;
}
#include "Core.h"

int main(int argc, char* argv[])
{
	double tab[] = {1,2,3};
	vector<double> v(tab,tab+3);
	Average<double> average;
	double result = average.Arithmetical(v);
	cin.get();
  return 0;
}

Proszę o pomoc przy znalezieniu błędu

3

Umiesc definicje metod w pliku naglowkowym.

0

Hmm C++ to już dla mnie odległa historia, ale spróbuję ;). Includujesz gdzieś Average.h? Przy main widzę tylko include Core.h

0

Sarrus:
W Core.h includuję wszystko co jest potrzebne w programie.

n0name_l
Dzięki to działa.

Pozostaje pytanie czemu tworzenie szablonu klasy musi wiązać się z umieszczaniem wszystkiego w pliku nagłówkowym?

0

Kolejne pliki *.cpp kompilują się niezależnie do siebie. Wiedzą o tym co znajduje się w drugim, tylko dzięki plikom nagłówkowym. Template działają na tej zasadzie że jak kompilator spotka wywołanie funkcji (w tym przypadku obiekt) który wymaga wersji z double, to generuje sobie funkcje która wymaga double, wstawiając to zamiast T. Potem jak spotka kolejne wywołanie np. z int, to znowu generuje nową wersję, tym razem z int itd. Ale, aby wygenerować taką funkcję musi wiedzieć jak ona powinna wyglądać, dlatego też musi być w pliku nagłówkowym.

0
  1. Zastanó się nad:
template <class T>
struct Average
{
    static T Arithmetical(vector<T> a);
    static T Geometric(vector<T> a);
    static T Weighted(vector<T> a, vector<T> w);
};
T result = pow(product,1./a.size());
0

@_13th_Dragon: Dzięki za sygnalizację błędu. Przed chwilą to zauważyłem.

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