#ifndef __TEST__
#define __TEST__
namespace std
{
template<typename T>
class list;
}
template<typename T>
void Pop(std::list<T> * l)
{
while(!l->empty())
l->pop();
}
#endif
i użyłem tej funkcji w moim pliku main. Otrzymuję błędy. Oczywiście wiem, że istnieje więcej parametrów szablonu std::list
(myślę, że alokator). Ale to nie ma znaczenia. Czy muszę znać pełną deklarację szablonu klasy szablonu, aby móc ją dalej zadeklarować?
EDYCJA: wcześniej nie używałem wskaźnika - to było odniesienie. Wypróbuję to za pomocą wskaźnika.
std::allocator<T>
__TEST__
jest zastrzeżonym identyfikatorem, nie używaj go .Odpowiedzi:
Problem nie polega na tym, że nie można przesłać dalej deklaracji klasy szablonu. Tak, musisz znać wszystkie parametry szablonu i ich wartości domyślne, aby móc poprawnie zadeklarować je dalej:
namespace std { template<class T, class Allocator = std::allocator<T>> class list; }
Ale nawet taka deklaracja forward
namespace std
jest wyraźnie zabroniona przez standard: jedyną rzeczą, którą możesz wprowadzić,std
jest specjalizacja szablonu , zwyklestd::less
w typie zdefiniowanym przez użytkownika. W razie potrzeby ktoś inny może zacytować odpowiedni tekst.Po prostu
#include <list>
i nie martw się o to.Aha, nawiasem mówiąc, każda nazwa zawierająca podwójne podkreślenie jest zarezerwowana do użytku przez implementację, więc powinieneś użyć czegoś takiego jak
TEST_H
zamiast__TEST__
. Nie wygeneruje ostrzeżenia ani błędu, ale jeśli w programie występuje konflikt z identyfikatorem zdefiniowanym w ramach implementacji, nie ma gwarancji, że skompiluje się lub uruchomi się poprawnie: jest źle sformułowany . Zabronione są również nazwy zaczynające się między innymi od podkreślenia, po którym następuje duża litera. Ogólnie rzecz biorąc, nie zaczynaj rzeczy od podkreślenia, chyba że wiesz, z jaką magią masz do czynienia.źródło
namespace std
okazji zgłaszanie rzeczy dalej jest zabronione ?#pragma once
zamiast # ifdef. Obecnie jest obsługiwany przez większość kompilatorów.#pragma
, właśnie dlatego. Chociaż jest to opcja.Rozwiązałem ten problem.
Wdrażałem warstwę OSI (okno suwaka, poziom 2) do symulacji sieci w C ++ (Eclipse Juno). Miałem ramki (szablon
<class T>
) i jego stany (wzorzec stanu, deklaracja forward).Rozwiązanie jest następujące:
W
*.cpp
pliku musisz dołączyć plik nagłówkowy, który przekazujesz dalej, tjifndef STATE_H_ #define STATE_H_ #include <stdlib.h> #include "Frame.h" template <class T> class LinkFrame; using namespace std; template <class T> class State { protected: LinkFrame<int> *myFrame; }
Jego CPP:
#include "State.h" #include "Frame.h" #include "LinkFrame.h" template <class T> bool State<T>::replace(Frame<T> *f){
I ... inna klasa.
źródło
using namespace
z plików nagłówkowych jest bardzo złą praktyką, ponieważ uniemożliwia każdemu używającemu tego pliku nagłówkowego możliwości używania lokalnych nazw, które w innym przypadku byłyby prawidłowe. Zasadniczo pokonuje cały punkt przestrzeni nazw.Deklaracja forward powinna mieć określoną pełną listę argumentów szablonu.
źródło
istnieje ograniczona alternatywa, z której możesz skorzystać
nagłówek:
class std_int_vector; class A{ std_int_vector* vector; public: A(); virtual ~A(); };
cpp:
#include "header.h" #include <vector> class std_int_vector: public std::vectror<int> {} A::A() : vector(new std_int_vector()) {} [...]
nie był testowany w prawdziwych programach, więc spodziewaj się, że nie będzie doskonały.
źródło