Szablony C++ H, zdefiniuj.hpp
Widziałem jakiś kod, w którym programista zdefiniował szablon klasy w a .pliku h i zdefiniował jego metody wplik hpp. Zaskoczyło mnie to.
Czy w C++ istnieją szczególne konwencje dotyczące szablonów i w jakich plikach powinny się znajdować?
Na przykład powiedzmy, że miałem szablon klasy Vector
z metodami operacji wektorowych (dodawanie, odejmowanie, kropka, itp.). Chciałbym również wyspecjalizować niektóre funkcje, jeśli argument szablonu jest float
(porównanie operatorów). Jak rozdzielić to wszystko między plikami (określ, czy .na,,,hpp,cpp).
7 answers
Zazwyczaj (z mojego doświadczenia, YMMV) plik hpp
jest plikiem #include
-ed CPP. Odbywa się to w celu podziału kodu na dwa pliki fizyczne, podstawowy plik include I plik implementacji, o którym użytkownicy biblioteki nie muszą wiedzieć. Robi się tak:
Super_lib.h (jedyny plik potrzebny Twoim klientom #include
)
template<...> class MyGizmo
{
public:
void my_fancy_function();
};
#include "super_lib_implementation.hpp"
Super_lib_implementacja.hpp (twoi klienci nie #include
to bezpośrednio)
template<...> void MyGizmo<...>::my_fancy_function()
{
// magic happens
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-19 21:30:41
To brzmi dla mnie niecodziennie. Definicja szablonu i wszystkie specjalizacje muszą być skompilowane wraz z jego deklaracją, z wyjątkiem export
templates, funkcji, która faktycznie nie istnieje.
C++0x wprowadza deklaracje szablonów extern
, które pozwalają definiować jawne specjalizacje w innym pliku źródłowym (jednostce tłumaczeniowej). Istnieje już jako rozszerzenie w GCC i prawdopodobnie innych platformach.
Podział na dwa pliki może pomóc " ukryć" implementacja trochę, albo pozwolić na jakieś lenistwo z doxygen, może.
Aha! Jest to również możliwe, aby poprawić czas kompilacji z wstępnie skompilowanych nagłówków. Kompilator może buforować nagłówki w zależności od Pliku. Oddzielny nagłówek " implementation "może zostać zmodyfikowany bez dotykania nagłówka" interface". Ale nie odwrotnie, nagłówek implementacji nadal zajmowałby większość czasu kompilacji, a zysk byłby bardzo delikatny i zależny od platformy i konkretnych zmian made. W koĹ "cu PCH skraca czas nad kilkoma plikami ĹşrĂłdĹ' owymi, a optymalizacja zaleĹźnoĹ "ci nagĹ' ăłwka nie ma sensu.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-19 21:30:00
Wydaje mi się, że jest to mylący sposób oddzielania kodu. .h
oznacza header i .hpp
dla C++ header powszechnie. Umieszczenie definicji szablonu w .hpp
, podczas gdy inny kod w {[1] } wydaje się nadużywać rozszerzenia pliku.
Kod szablonu jest zwykle zapisywany w jednym nagłówku wraz z deklaracją szablonu, lub w innym nagłówku, który może być również specjalnie zakończony jak .tcc
lub coś, a następnie dołączony do nagłówka, gdzie szablon deklaracje są wprowadzane. Ale tak naprawdę rozszerzenie pliku nie ma znaczenia, o ile jesteś konsekwentny w swoim projekcie.
Wyjątki są wtedy, gdy używasz jawnej instancji i wiesz dokładnie, jakich instancji będziesz potrzebować. Wyobraź sobie, że masz szablon i dokładnie dwie instancje tego szablonu:
template<typename T>
struct SymbolTable {
T *lookup();
// ...
};
template struct SymbolTable<GlobalSym>;
template struct SymbolTable<LocalSym>;
Nie musisz umieszczać definicji lookup
i innych w nagłówku. Możesz umieścić je wszystkie w pliku .cpp
, obok dwóch jawnych dyrektyw instancyjnych.
Ostatni punkt, o który pytasz, dotyczy innego tematu: wyraźnych specjalizacji. Zalecam Ci osobne pytanie na ten temat. W skrócie, jednoznaczne definicje specjalizacji, w których wszystkie argumenty szablonu mają konkretne wartości/typy, powinny być umieszczone w pliku .cpp
, ale ich deklaracje muszą być umieszczone w nagłówku (aby powiedzieć innym, że te niektóre elementy są wyspecjalizowane).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-19 22:06:46
Nigdy nie słyszałem o umieszczaniu deklaracji klas w .h
i definicji szablonów w .hpp
. Każdy projekt, który widziałem, przyjął podejście, że .h
i .hpp
oznaczają to samo i powinieneś standaryzować na jednym (Zwykle .h
).
Metody szablonów mogą być umieszczone na końcu pliku .h
lub mogą być umieszczone w oddzielnych plikach -inl.h
(Jak sugeruje na przykład Google C++ Style Guide).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-19 21:17:40
Myślę, że jeden aspekt oddzielenia interfejsu (.h) i realizacji (.plik hpp) jest to, że użytkownik szablonu (tj. inny programista) powinien tylko patrzeć na .plik h, aby zrozumieć, jak korzystać z szablonu bez rozpraszania się przez jego rzeczywistą realizację.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-19 21:18:15
Jeśli zdefiniujemy szablon klasy w a .plik h, i zdefiniuj jego metody w a .plik hpp Następnie musimy #include
the .plik hpp w .plik H. Łatwiej jest po prostu zdefiniować metody na końcu .plik h (wtedy niepotrzebny plik hpp).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-19 21:18:14
Biblioteka Boost wykorzystuje".hpp " dla nagłówków zawierających deklarację i implementację. W takich przypadkach nie ma potrzeby łączenia się z (wstępnie skompilowaną) biblioteką.
W odniesieniu do Boost idea, takie rozszerzenie jak".inl "może być dobrym pomysłem na opisanie" implementacji " pliku źródłowego nagłówka deklaracji szablonu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-17 18:08:24