latajacaryba Temat założony przez niniejszego użytkownika |
Dlaczego do przeciążenia szablonu funkcji muszę jeszcze raz zadeklarować template<typ> » 2017-02-02 00:21:14 Witam. Pisałem kod, #include <iostream> using namespace std; template < typename Typ >
Typ funk( const Typ obj[], int rozm ) { cout << "dla cstringa\n" << obj << endl; }
Typ funk( const Typ & obj ) { cout << "Wywolano funkcje dla: " << obj << endl; return obj; }
int main() { funk( 5 ); funk( "ala ma kota", 12 ); funk( funk( 'a' ) ); return 0; }
Kiedy kod był w takiej postaci, bez umieszczenia w kodzie drugiego template wyszły błędy: ||=== Build: Debug in EKN (compiler: GNU GCC Compiler) ===| D:\Inne_z_pulpitu\EKN\main.cpp|9|error: 'Typ' does not name a type| D:\Inne_z_pulpitu\EKN\main.cpp||In function 'int main()':| D:\Inne_z_pulpitu\EKN\main.cpp|16|error: no matching function for call to 'funk(int)'| D:\Inne_z_pulpitu\EKN\main.cpp|16|note: candidate is:| D:\Inne_z_pulpitu\EKN\main.cpp|5|note: template<class Typ> Typ funk(const Typ*, int)| D:\Inne_z_pulpitu\EKN\main.cpp|5|note: template argument deduction/substitution failed:| D:\Inne_z_pulpitu\EKN\main.cpp|16|note: mismatched types 'const Typ*' and 'int'| D:\Inne_z_pulpitu\EKN\main.cpp|18|error: no matching function for call to 'funk(char)'| D:\Inne_z_pulpitu\EKN\main.cpp|18|note: candidate is:| D:\Inne_z_pulpitu\EKN\main.cpp|5|note: template<class Typ> Typ funk(const Typ*, int)| D:\Inne_z_pulpitu\EKN\main.cpp|5|note: template argument deduction/substitution failed:| D:\Inne_z_pulpitu\EKN\main.cpp|18|note: mismatched types 'const Typ*' and 'char'| D:\Inne_z_pulpitu\EKN\main.cpp||In instantiation of 'Typ funk(const Typ*, int) [with Typ = char]':| D:\Inne_z_pulpitu\EKN\main.cpp|17|required from here| D:\Inne_z_pulpitu\EKN\main.cpp|8|warning: no return statement in function returning non-void [-Wreturn-type]| ||=== Build failed: 3 error(s), 3 warning(s) (0 minute(s), 0 second(s)) ===|
Dlaczego muszę jeszcze raz umieszczać deklarację po przeciążeniu szablonu? PS. czym się różni template<class> od template<typename> ? |
|
pekfos |
» 2017-02-02 00:57:27 Typ funk( const Typ & obj ) { cout << "Wywolano funkcje dla: " << obj << endl; return obj; }
|
A czym jest Typ, bez tej linii? |
|
michal11 |
» 2017-02-02 09:56:18 Przyjęło się, że class w template używa się gdy chcemy "zadeklarować", że parametrem szablonu mogą tylko klasy, typename dopuszcza dodatkowo typy podstawowe. Ale z tego co wiem nie jest to nakaz a raczej konwencja nazewnicza. |
|
latajacaryba Temat założony przez niniejszego użytkownika |
» 2017-02-02 18:18:12 [Cpp] template < typename Typ > //TU JEST
Typ funk( const Typ obj[], int rozm ) { cout << "dla cstringa\n" << obj << endl; } //template< typename Typ > BEZ TEGO NIE DZIALA Typ funk( const Typ & obj ) { cout << "Wywolano funkcje dla: " << obj << endl; return obj; }[/cpp] Jak widac wyzej, jest deklaracja takiego szablonu typu(?). Wiec gdzie problem?
|
|
mokrowski |
» 2017-02-02 18:26:49 Problem w tym że jedna funkcja ma 2 argumenty a druga 1. To dwie oddzielne funkcje bo w C++ jest polimorfizm :-) To funkcja jest "szablonowana" a nie dany (jako jej argument) typ. |
|
latajacaryba Temat założony przez niniejszego użytkownika |
» 2017-02-02 18:55:18 Ok, ale czy to oznacza, że przed każdym szablonem funkcji mam dawać template<...> ? template < nametype Typ > void Switch( Typ obj1, Typ obj2 );
template < nametype Typ > void Switch( Typ obj1, Typ obj2, int a );
template < nametype Typ > void Switch( Typ obj1, Typ obj2, double b );
? Bo tak właściwie, to co jest szablonem funkcji? template < nametype Typ > void Switch( Typ obj1, Typ obj2, double b );
A może oba razem? I jeszcze jedno: Czytam Prata i był wątek o specjalizacji szablonu. Z tego co zrozumiałem, to chodzi mniej więcej o to: struct Struktura { int a; double b; };
template < nametype Typ > void Swap( Typ obj1, Typ obj2 ) { Typ przeniesienie = obj1; obj1 = obj2; obj2 = przeniesienie; }
template <> void Swap( Struktura obj1, Struktura obj2 ) { }
Jeśli tak jest to po co są specjalizacje? Nie lepiej stworzyć normalną funkcję void Swap( Struktura obj1, Struktura obj2 ) ? Przecież taka funkcja jest zawsze "wyżej w hierarchii" i jeśli zrobimy tak: int main() { Struktura obj1 = { 5, 0.3 }; Struktura obj2 = { 1, 2.5 }; Swap( obj1, obj2 ); }
Zawsze wykona nam się "normalna", standardowa funkcja. Więc do czego są specjalizacje? |
|
mokrowski |
» 2017-02-02 19:10:20 Przed każdym szablonem funkcji powinieneś wpisać template bo... to szablon funkcji :-)
Szablon funkcji rozciąga się od słowa template aż do końca tejże funkcji jeśli ją definiujesz lub do ; jeśli ją tylko deklarujesz (np. w using)
Szybkie i oczywiście niepełne tłumaczenie po co jest specjalizacja funkcji to... Wyobraź sobie że szablon funkcji załatwia 90% przypadków typów które może dostać. Jednak jest kilka "wrednych" które trzeba obsłużyć inaczej. Np napisałeś funkcję PrintValues(...) która drukuje na ekran zawartość dowolnego kontenera. Jednak jeśli dostanie kontener z Twoją klasą, trochę inaczej powinna dostawać się do pól do wyświetlenia. Wtedy dodajesz specjalizację funkcji dla kontenerów z Twoją klasą.
Co do Twojego pytania o to po co tworzyć specjalizację jeśli można normalną funkcję.... Zapomniałeś (albo nie doczytałeś) o specjalizacji częściowej funkcji. Jest jeszcze kilka innych powodów ale nie ma sensu tworzyć elaboratów jak czytasz Prat'ę. Tam jest to wyjaśnione. |
|
latajacaryba Temat założony przez niniejszego użytkownika |
» 2017-02-02 20:11:37 Być może nie doszedłem jeszcze do tej częściowej specjalizacji funkcji. Na razie dzięki, odezwę się w tym poście, gdy książka nie rozwieje moich wątpliwości ;) |
|
« 1 » 2 |