Jak jawnie utworzyć wystąpienie funkcji szablonu?

117

Mam funkcję szablonu z jednym argumentem. Muszę utworzyć wystąpienie tej funkcji bez wywoływania tej funkcji, co oznacza jawnie, że muszę utworzyć wystąpienie.

Mam taką funkcję:

template <class T> int function_name(T a) {}

Utworzyłem tę funkcję w następujący sposób:

template int function_name<int>(int);

Ale mam następujące błędy:

error: expected primary-expression before 'template'
error: expected `;' before 'template'
Balaji
źródło

Odpowiedzi:

182

[EDYCJA 2]: Zwróć uwagę, że było pewne zamieszanie dotyczące kodu w pierwotnym pytaniu z powodu problemów z formatowaniem kodu. Aby uzyskać więcej informacji, zobacz odpowiedź Anthony'ego Hatchkinsa.

Jeśli naprawdę chcesz utworzyć instancję (zamiast specjalizować się lub coś w tym rodzaju), zrób to:

template <typename T> void func(T param) {} // definition

template void func<int>(int param); // explicit instantiation.

[EDYTUJ] Wydaje się, że istnieje (dużo) nieporozumień dotyczących jawnej instancji i specjalizacji. Kod, który opublikowałem powyżej, dotyczy jawnej instancji . Składnia specjalizacji jest inna. Oto składnia specjalizacji:

template <typename T> void func(T param) {} // definition

template <> void func<int>(int param) {} // specialization

Zwróć uwagę, że nawiasy ostre po szablonie!

hrnt
źródło
3
to jest tworzenie instancji czy specjalizacja ?
Nawaz,
5
Nie prawda. Możesz powiedzieć kompilatorowi, aby jawnie utworzył wystąpienia szablonów. Więcej szczegółów w Google dla „jawnej instancji szablonu w C ++”.
hrnt
8
@Nawaz: mylisz się. Oczywiście, to kompilator zawsze tworzy instancję, ta linia jest żądaniem od programisty do kompilatora, aby utworzyć instancję szablonu. Jeśli masz kopię standardu C ++, przeczytaj 14.7.2 Jawna instancja
David Rodríguez - dribeas
16
Specjalizacja oznacza, że ​​prawdopodobnie zmieniasz jej implementację. Tworzenie instancji oznacza po prostu, że przypisujesz ją do konkretnej jednostki kompilacji, być może po to, aby wziąć jej unikalny adres lub udostępnić ją jako funkcję biblioteczną lub w celu zmniejszenia nadmiaru.
CashCow
3
@hrnt: Myślę, że masz rację. @Ashot: Właśnie zauważyłem, że składnia nie ma template<>formy. To, co napisał, różni się od specjalizacji . +1 za nauczenie mnie tej nowej rzeczy. Usuwam swój post. : D
Nawaz,
20

Twój kod jest poprawny.

Komunikat o błędzie dotyczy miejsca w kodzie, którego tutaj nie zacytowałeś.

Aktualizacja:

Oryginalny kod to

template <class T> int function_name(T a) {}
template int function_name<int>(int);

i to było poprawne.

Ale nie zostało zacytowane i dlatego wyglądało tak:

template int function_name(T a) {}
template int function_name(int);

Generuje następujący błąd

a.cpp:1: error: explicit instantiation of non-template int function_name
a.cpp:1: error: expected `;' before ‘(’ token
a.cpp:3: error: function_name is not a template function

co wyraźnie różni się od cytowanego przez OP.

W tym wariancie druga linia jest w porządku ( <int>można ją tutaj pominąć), ale pierwsza linia jest uszkodzona. Kompilator nie może odgadnąć, że Tjest to parametr szablonu.

Antony Hatchkins
źródło
Technicznie to nie jego kod, to była edycja Billa :) Oryginalny kod jest template int function_name( T a) { }itemplate int function_name(int);
hrnt
@hrnt Oryginalny kod nie został poprawnie sformatowany, ale był poprawny. Gdybym był Balaji , wróciłbym i zaakceptował twoją odpowiedź, gdyby uznał ją za przydatną, jednak dla mnie (i prawdopodobnie dla kogokolwiek innego) twoja odpowiedź (choć sama w sobie jest całkowicie słuszna) nie odpowiada na pytanie.
Antony Hatchkins
@hrnt Masz rację, że oryginalny kod tak wyglądał. Ale z powodu wywnioskowanego argumentu szablonu nadal działa. Muszę zgodzić się z Antony Hatchkinsem, że błąd wynika z kodu, którego OP nie zacytował, jednak myślę, że twoja odpowiedź jest nadal przydatna dla osób, które nie wiedziały o jawnej instancji.
mpark
Weź mnie na przykład. Przeszukałem tę stronę w Google, gdy chciałem odświeżyć swoją dobrze zapomnianą wiedzę o jawnej instancji - i niewiele mi to pomogło. Jeśli chodzi o mnie, nie ma zamieszania co do składni. To, co może powodować zamieszanie co do jawnej instancji, to jej użycie
Antony Hatchkins,
@AntonyHatchkins Ach, prawda - nie spojrzałem na źródło pierwotnego pytania, tylko na to, jak wyglądało na moim ekranie. Dam +1 i poprawię moją pierwotną odpowiedź, aby zwrócić uwagę na niejasność dotyczącą pierwotnego pytania.
godz.