13.15 — Szablony aliasów

W lekcji 10.7 -- Typedefs i aliasy typów, omówiliśmy, w jaki sposób aliasy typów pozwalają nam zdefiniować alias dla istniejący typ.

Tworzenie aliasu typu dla szablonu klasy, w którym wszystkie argumenty szablonu są jawnie określone, działa tak samo jak normalny alias typu:

#include <iostream>

template <typename T>
struct Pair
{
    T first{};
    T second{};
};

template <typename T>
void print(const Pair<T>& p)
{
    std::cout << p.first << ' ' << p.second << '\n';
}

int main()
{
    using Point = Pair<int>; // create normal type alias
    Point p { 1, 2 };        // compiler replaces this with Pair<int>

    print(p);

    return 0;
}

Takie aliasy można definiować lokalnie (np. wewnątrz funkcji) lub globalnie.

Szablony aliasów

W innych przypadkach możemy potrzebować aliasu typu dla klasy szablonu, w której nie wszystkie argumentów szablonu są zdefiniowane jako część aliasu (i zamiast tego będą dostarczane przez użytkownika typu alias). W tym celu możemy zdefiniować szablon aliasu, który jest szablonem, którego można używać do tworzenia instancji aliasów typów. Podobnie jak aliasy typów nie definiują odrębnych typów, tak szablony aliasów nie definiują odrębnych typów.

Oto przykład, jak to działa:

#include <iostream>

template <typename T>
struct Pair
{
    T first{};
    T second{};
};

// Here's our alias template
// Alias templates must be defined in global scope
template <typename T>
using Coord = Pair<T>; // Coord is an alias for Pair<T>

// Our print function template needs to know that Coord's template parameter T is a type template parameter
template <typename T>
void print(const Coord<T>& c)
{
    std::cout << c.first << ' ' << c.second << '\n';
}

int main()
{
    Coord<int> p1 { 1, 2 }; // Pre C++-20: We must explicitly specify all type template argument
    Coord p2 { 1, 2 };      // In C++20, we can use alias template deduction to deduce the template arguments in cases where CTAD works

    std::cout << p1.first << ' ' << p1.second << '\n';
    print(p2);

    return 0;
}

W tym przykładzie definiujemy szablon aliasu o nazwie Coord jako alias dla Pair<T>, gdzie parametr szablonu typu T zostanie zdefiniowany przez użytkownika Coord alias. Coord jest szablonem aliasu i Coord<T> jest aliasem typu instancji dla Pair<T>. Po zdefiniowaniu możemy użyć Coord gdzie użyjemy Pair, I Coord<T> gdzie użyjemy Pair<T>.

W tym przykładzie warto zwrócić uwagę na kilka rzeczy.

Po pierwsze, w przeciwieństwie do aliasów typu normalnego (które można zdefiniować wewnątrz bloku), szablony aliasów muszą być zdefiniowane w zakresie globalnym (tak jak wszystkie szablony muszą).

Po drugie, przed C++20, musimy jawnie określić argumenty szablonu, gdy tworzymy instancję obiektu przy użyciu szablonu aliasu. Począwszy od C++20, możemy używać dedukcji szablonu aliasów, która wydedukuje typ argumentów szablonu z inicjatora w przypadkach, gdy typ aliasu działałby z CTAD.

Po trzecie, ponieważ CTAD nie działa na parametrach funkcji, kiedy używamy szablonu aliasu jako parametru funkcji, musimy jawnie zdefiniować argumenty szablonu używane przez szablon aliasu. Innymi słowy, robimy to:

template <typename T>
void print(const Coord<T>& c)
{
    std::cout << c.first << ' ' << c.second << '\n';
}

Nie to:

void print(const Coord& c) // won't work, missing template arguments
{
    std::cout << c.first << ' ' << c.second << '\n';
}

To nie różni się od tego, gdybyśmy użyli Pair lub Pair<T> zamiast Coord lub Coord<T>.

guest
Twój adres e-mail nie zostanie wyświetlony
Znalazłeś błąd? Zostaw komentarz powyżej!
Komentarze związane z poprawkami zostaną usunięte po przetworzeniu, aby pomóc zmniejszyć bałagan. Dziękujemy za pomoc w ulepszaniu witryny dla wszystkich!
Awatary z https://gravatar.com/ są połączone z podanym adresem e-mail.
Powiadamiaj mnie o odpowiedziach:  
34 Komentarze
Najnowsze
Najstarsze Najczęściej głosowane
Wbudowane opinie
Wyświetl wszystkie komentarze