Unresolved Externals LNK2001 - Template class

0

Witam.
Dlaczego przy próbie kompilacji poniższego kodu otrzymuję błędy?

Data.h

#pragma once
#include <array>
#include <vector>
#include <string>
#include <fstream>
#include "Globals.h"
#include "Color.h"
#include "Mouse.h"

template <size_t Colors_Size, size_t Mouses_Size>
class Data
{

	void Load_Accounts(std::string Name);

public:

	std::array<Color, Colors_Size> Colors;
	std::array<Mouse, Mouses_Size> Mouses;

	std::vector<std::array<std::string, 2>> Accounts;
	
	

	void Initialize(std::string Name);

};

Data.cpp

#include "Data.h"



template <size_t Colors_Size, size_t Mouses_Size> void Data<Colors_Size, Mouses_Size>::Initialize(std::string Name)
{

}

template <size_t Colors_Size, size_t Mouses_Size> void Data<Colors_Size, Mouses_Size>::Load_Accounts(std::string Name)
{

}

main.cpp

Data<5, 5> Data_Instance;
Data_Instance.Initialize("name");
Error	2	error LNK1120: 1 unresolved externals
Error	1	error LNK2001: unresolved external symbol "public: void __thiscall Data<5,5>::Initialize(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?Initialize@?$Data@$04$04@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)	
0

U mnie kompiluje sie poprawnie.

0

Gdy cały podany powyżej kod jest w jednym pliku program kompiluję się poprawnie jednak w przypadku podzielenia go na 3 pliki pojawiają się dwa błędy (Visual Studio 2015 Community).

2

Oho, to problem z szablonami numer 1.

No ile razy można powtarzać, że źródło szablonu musi być w pliku nagłówkowym. :-( Skąd biedny kompilator ma wiedzieć jak wygląda szablon, który próbujesz wykorzystać? Przecież musi powstawiać Twoje typy w parametry szablonu i wygenerować kod. Jak niby ma to zrobić nie mając dostępu do źródła?

To jest absolutnie podstawowa wiadomość związana z szablonami w C++.

W pliku źródłowym może być konkretyzacja szablonu dla zadanych parametrów (patrz extern template). Musi tam być całkowita specjalizacja szablonu. Ale postać ogólna musi być dostępna i dlatego musi być w pliku nagłówkowym.

1

Temat poruszany milion razy. Nie możesz (bez trików) definiować niepełnej specjalizacji szablonu poza deklaracją.
Przerób jakiś kurs podstaw C++ zanim zaczniesz zadawać pytania na forum :/

0

No ile razy można powtarzać, że źródło szablonu musi być w pliku nagłówkowym
Noo, nie musi, ale to najprostszy i najmniej WTF-owy sposób na rozwiązanie problemu.

0

@Endrju
Jeżeli w pliku .cpp zamieścimy konkretyzacje dla wszystkich parametrów szablonu jakich użycie przewidujemy, możemy zachować typowy podział na nagłówek i kod:

klasa.h

#pragma once

template <typename T>
class Klasa
{
public:
	void foo(T t);
};

klasa.cpp

#include "klasa.h"
#include <iostream>

template<typename T>
void Klasa<T>::foo(T t)
{
	std::cout << t << std::endl;
}

template class Klasa<int>;
template class Klasa<const char*>;

main.cpp

#include "klasa.h"

int main()
{
	Klasa<int> a;
	a.foo(3);

	Klasa<const char*> b;
	b.foo("ala");
}

Niestety w takiej sytuacji można będzie używać jedynie Klasa<int> i Klasa<const char*>, ale już nie Klasa<float>. To czyni rozwiązanie bezużytecznym w większości przypadków...

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