第五节 · 特殊人格 · 模板特例化

C++20 引入的 Concepts 让模板约束更加清晰和易用,大大改善了模板编程的体验和错误信息。


为什么需要 Concepts

// 没有 Concepts 时的错误信息难以理解
template<typename T>
T add(T a, T b)
{
    return a + b;
}

struct Foo {};

int main()
{
    add(Foo{}, Foo{});  // 编译错误,但错误信息很长很复杂
    return 0;
}

定义 Concept

#include <concepts>

// 简单的 Concept
template<typename T>
concept Numeric = is_arithmetic_v<T>;

// 使用 requires 表达式
template<typename T>
concept Addable = requires(T a, T b) {
    { a + b } -> same_as<T>;  // 要求 a + b 有效且返回 T
};

// 更复杂的约束
template<typename T>
concept Container = requires(T c) {
    typename T::value_type;      // 要求有 value_type 类型
    typename T::iterator;        // 要求有 iterator 类型
    { c.begin() } -> same_as<typename T::iterator>;
    { c.end() } -> same_as<typename T::iterator>;
    { c.size() } -> convertible_to<size_t>;
};

使用 Concept


标准库 Concepts


复合 Concepts


requires 表达式详解


基于 Concept 的重载


实际应用:Iterator Concepts


自定义类型满足 Concept


Concept 提升错误信息


习题

  • 定义一个 Serializable concept,要求类型有 serialize()deserialize() 方法。

  • 使用 concepts 重写一个泛型排序函数,要求元素可比较。

  • 解释 concepts 相比 SFINAE 的优势。

Last updated