13-15 别名模板

在第10.7节——类型别名与类型别名中,我们讨论了如何通过类型别名为现有类型定义别名。

为所有模板参数均显式指定的类模板创建类型别名type alias时,其操作方式与普通类型别名完全相同:

#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;
}

此类别名可在局部(例如函数内部)或全局范围内定义。


别名模板

在其他情况下,我们可能需要为模板类定义类型别名,但别名中并非所有模板参数都已定义(这些参数将由类型别名的使用者提供)。为此,我们可以定义别名模板alias template,——这是一种可用于实例化类型别名的模板。正如类型别名本身并不定义独立类型,别名模板同样不定义独立类型。

以下示例展示其工作原理:

#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;
}

image

在此示例中,我们定义了一个名为 Coord 的别名模板,作为 Pair 的别名,其中类型模板参数 T 将由 Coord 别名的使用者定义。Coord 是别名模板,而 Coord 是 Pair 的实例化类型别名。定义完成后,我们可以在需要使用 Pair 的地方使用 Coord,在需要使用 Pair 的地方使用 Coord

此示例有几点值得注意:

首先,与普通类型别名(可在代码块内定义)不同,别名模板必须在全局作用域中定义(所有模板皆如此)。

其次,在C++20之前,使用别名模板实例化对象时必须显式指定模板参数template arguments 。自C++20起,我们可使用别名模板推导机制alias template deduction——当别名类型支持CTAD时,该机制能从初始化表达式推导模板参数类型。

第三,由于CTAD不适用于函数参数function parameters,当别名模板作为函数参数时,必须显式定义其模板参数。换言之,我们这样做:

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

不是这样:

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

这与我们使用 Pair 或 Pair 代替 Coord 或 Coord 并无二致。

posted @ 2025-12-24 21:02  游翔  阅读(16)  评论(0)    收藏  举报