Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Dlaczego do przeciążenia szablonu funkcji muszę jeszcze raz zadeklarować template<typ>

Ostatnio zmodyfikowano 2017-02-03 20:28
Autor Wiadomość
Monika90
» 2017-02-03 08:59:27
Nie doszedłeś i nie dojdziesz, bo w C++ nie ma częściowej specjalizacji szablonów funkcji.

Możesz mieć szablon funkcji która nie przyjmuje parametrów
C/C++
template < class T >
T create() { return { }; }

W takiej sytuacji nie można użyć przeciążenia żeby uzyskać specjalne zachowanie dla jakiegoś wybranego typu, więc pozostaje jawna specjalizacja, zwana też pełną specjalizacją.
C/C++
template <>
int create() { return 5; }

P-157261
mokrowski
» 2017-02-03 10:21:07
Racja co do specjalizacji częściowej funkcji. Tej nie ma. Wyraziłem się nieprecyzyjnie za co przepraszam miałem na myśli metafunkcje np. z <type_traits> no ale to .. struktury (czyli klasy) :-)
Dość że co do funkcji można jeszcze sobie pozwolić np. na:
C/C++
template < typename T, unsigned N >
void function( T( & arr )[ N ] ) {
    cout << "Array size: " << N << endl;
}

// Użycie takiej funkcji to:
int arr[ 12 ];
function( arr ); // Automatyczne podstawienie argumentu określi wielkość N
Parametr domyślny dla funkcji:
C/C++
template < typename T >
T count( T a, T b, T c = T( 3 ) ) {
    return a + b + c;
}
// Konkretyzacja powiedzie się dla:
count( 1, 2 ); // c będzie miało wartość 3
count( 1, 2, 5 ); // c będzie miało wartość 5
Wyłączenie specjalizacji dla typu:
C/C++
template < typename T >
T func( T arg ) {
    return arg;
}

template <>
float func < float >( float ) = delete;
// Konkretyzacja dla float się nie powiedzie
No i parametrem szablonu może być:
C/C++
template <
int a, // Typ integral lub POD
int( & array )[ 5 ], // Lwartość tablicy
int( * ptrFun )( int ), // Wskaźnik na funkcję
int( X < 6 >::* a )[ 11 ] // Wskaźnik na członka w klasie X "szablonowanej" int
> class Wow;
... oraz inny szablon
P-157263
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-02-03 17:49:01
Oki, z tego co wyczytałem, to konkretyzacje dzielą się na:
- niejawna - kompilator na podstawie szablonu tworzy funkcję dla naszego typu, ale dopiero gdy w kodzie znajdzie się wywołanie funkcji z danymi typami, przyklad
C/C++
template < nametype T >
void Swap( T & a, T & b ) {...}
int main() {
    int a = 5, b = 6;
    double c = 1.4, d = 8.12;
    float e = 5.6, f = 0.01;
   
    Swap( a, b ); // kompilator na podstawie szablonu tworzy funkcje dla T bedacego typem int
    Swap( c, d ); // kompilator na podstawie szablonu tworzy funkcje dla T bedacego typem double
    Swap( c, e ); // kompilator na podstawie szablonu tworzy funkcje dla T bedacego typem float
}
- jawna - sami tworzymy funkcję (różnica od niejawnej jest taka, że tu możemy mieć inne ciało funkcji i jest ona OD RAZU tworzona [nie jak w w/w przypadku] ) przyklad potem.

Specjalizacja:
- jawna - szablon funkcji (np. Swap) ma być inny dla danego typu. Od jawnej konkretyzacji różni się tym, że tam funkcja była od razu definiowana, a tu jakby jest inny szablon, więc jeśli wywołania funkcji z danymi argumentami nie będzie, to taka definicja funkcji nie zostanie stworzona. przyklad:
C/C++
//Konkretyzacja i specjalizacja
template < nametype T >
void Swap( T & a, T & b ) {...}
template <> void Swap < int >( double & a, double & b ) {...} // specjalizacja - funkcja nie jest generowana teraz.
template void Swap < int >( float & a, float & b ) {...} // funkcja jest od razu definiowana
int main() {
    int a = 5, b = 6;
    double c = 6.7, d = 0.1;
    Swap( a, b ); // kompilator na podstawie szablonu tworzy funkcje dla T bedacego typem int (dopiero teraz)
    Swap( c, d ); // generowana dopiero teraz teraz wedlug "nowego szablonu" dla tych typow (specjalizacji)
}

- niejawna specjalizacja - nie mam pojęcia, co to. Domyślam się, że po prostu szablon funkcji.


Proszę mnie poprawić jeśli się mylę :)

I jeszcze 2 pytania:
1.
template < nametype A, nametype B > void Swap( A & a, B & b ) {...}
?
Co zrobić w przypadku konkretyzacji lub specjalizacji, tzn. przy specjalizacji mamy taką
konstrukcję:
template <> typ_funk nazwa_funk < typ >( arg, arg );
? Co mam wstawić w <typ> ? Przy w/w przykładach było łatwo, bo oba argumenty były int, więc sprawa była prosta. Ale co teraz? Użyć
decltype
? To samo, kiedy typem funkcji ma być zmienna A + zmienna B
template < nametype A, nametype B > decltype Swap( A & a, B & b ) {...}
?
2. Czy czymś jeszcze różni się specjalizacja od konkretyzacji (pomijam drobnostki jak <> po template).
Sorry, że się tak rozpisałem. :)

PS. @mokrowski
No i parametrem szablonu może być
A klasa może być (oczywiście przeładuje potrzebne operatory)?
P-157279
mokrowski
» 2017-02-03 17:59:58
Parametrem szablonu dodatkowo/także może być oprócz typów POD i klas....
P-157280
carlosmay
» 2017-02-03 18:00:31
Parametrem szablonu może być wszystko, co prawidłowo będzie działać w ciele funkcji (metod). Jeśli nauczysz klase obsługi operatorów użytych w ciele szablonu, klasa też może być dedukowanym typem tego szablonu.
P-157281
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-02-03 20:28:19
Dzięki, już rozumiem. A co z moimi domysłami? Są prawdziwe?
P-157296
1 « 2 »
Poprzednia strona Strona 2 z 2