required from here - błąd przy użyciu szablonów

0

Witam,

CodeBlocks wyświetla mi następujący błąd:

required from here

pojawia się on w linii, gdzie wywołuję metodę:

G.generujGraf(0.75);

Fragment klasy Graf w pliku Graf.h:

template <typename T>
class Graf
{
...
T V;    // Liczba wierzcholków
void generujGraf(float procent);
...
}

metoda w pliku Graf.cpp:

template <typename T>
void Graf<T>::generujGraf(float procent)
{
    srand( time( NULL ) );
    T maxIloscKrawedzi = (this->V*(this->V-1))/2;
    T liczbaKrawedzi = maxIloscKrawedzi * procent;
    T licznik = 0;
    T x,y,w;
...

}

kod bez szablonów działał wcześniej dobrze, natomiast błąd który otrzymuję obecnie niestety nic mi nie mówi...

Dodam, że utworzenie obiektu przebiega bez problemu, część innych metod działa poprawnie, niektóre wyświetlają dokładnie ten sam błąd - required from here.
Czym jest to spowodowane?

2
  1. Wklej cały błąd.
  2. nie umieszczaj definicji szablonów w plikach .cpp
0

Ad 1.

Compiling: main.cpp
In file included from Graf.h0,
main.cpp
Graf.cpp: In instantiation of 'void Graf<T>::generujGraf(float) [with T = int]':
main.cpp23: required from here

Ad 2.
Czemu? Do tej pory tak robiłem i działało to bez problemu

0

Ad 2.
Czemu? Do tej pory tak robiłem i działało to bez problemu

Nie da się z szablonami klas.

Prosty przykład:

 // plik foo.hpp
template <typename T>
class Foo
{
	T value;
public:
	Foo(T);
	template <typename T>
		friend std::ostream& operator<<(std::ostream& os, const Foo<T>& f);
};


// plik foo_impl.hpp
#include "foo.hpp"
template <typename T>
Foo<T>::Foo(T v)
	:value{ v }
{}

template <typename T>
std::ostream& operator<< (std::ostream& os, const Foo<T>& f)
{
	return os << f.value;
}


// plik source.cpp
#include "foo_impl.hpp"
int main()
{
	Foo<int> foo(4);
	std::cout << foo << std::endl;
	std::cin.get();
}
2

To brzydkie rozwiązanie, traktujesz .cpp jak nagłówek. Jeśli chcesz oddzielić deklarację szablonu od definicji, lepiej traktuj nagłówki jak nagłówki i deklarację trzymaj w nagłówku z końcówką _fwd.hpp (tak robi Boost), a definicje w "zwykłym" nagłówku (czyli miałbyś foo_fwd.hpp i foo.hpp), albo w "zwykłym" trzymaj deklarację, a implementację w _impl.hpp (czyli miałbyś foo.hpp i foo_impl.hpp) - tak proponuje Sutter (np. tu: https://herbsutter.com/gotw/_101/ )

Niemniej jednak, to powinno działać, ale cały czas nie wkleiłeś całego komunikatu błędu. Wejdź w okno kompilacji i przekopiuj komunikat od kompilatora, a nie błędnie odfiltrowaną wersję przez środowisko.

0

Korzystam z rozwiązania nr 3 z powyższego artykułu

Nie chce mi się w tej chwili zagłębiać w przyczynę, ale kod z rozwiązania 3 nie kompiluje się ani pod GCC ani pod Visualem.

0

Nie chce mi się w tej chwili zagłębiać w przyczynę, ale kod z rozwiązania 3 nie kompiluje się ani pod GCC ani pod Visualem.

Kompiluje się. Trzeba ustawić guardy w pliku cpp i dopisać ciało metody SetValue. visual

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