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).

Author: rhubarb, 2010-08-20

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
}
 18
Author: John Dibling,
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.
 2
Author: Potatoswatter,
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).

 2
Author: Johannes Schaub - litb,
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).

 1
Author: Josh Kelley,
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ę.

 1
Author: Andre Holzner,
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).

 0
Author: M. Sadeq H. E.,
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.

 0
Author: Maestro,
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