C++20中的`requires`关键字使用详解

418 阅读3分钟

C++20中的requires关键字使用详解

C++20引入了概念(Concepts),提供了一种新的机制来约束模板参数,使得模板编程更加类型安全和易读。requires关键字是概念的核心部分,用于指定模板参数必须满足的条件。本文将详细介绍requires关键字的使用方法及其在C++20中的作用。

什么是requires

requires关键字用于定义一个要求(Requirement),即模板参数需要满足的条件。这些条件可以是类型特性、表达式有效性等。通过requires关键字,可以在模板定义时对模板参数进行约束,从而保证传入的类型符合预期。

requires的基本用法

requires关键字有两种主要用法:requires-clauserequires-expression。我们通过示例来介绍它们的用法。

1. requires-clause用法

requires-clause用于直接在模板函数或类的声明中添加约束。

示例一:约束函数模板参数

#include <iostream>
#include <concepts>

template <typename T>
requires std::integral<T>
T add(T a, T b) {
    return a + b;
}

int main() {
    std::cout << add(1, 2) << std::endl;           // 输出:3
    // std::cout << add(1.5, 2.5) << std::endl;    // 编译错误,double不满足std::integral
    return 0;
}

在这个示例中,add函数模板被requires std::integral<T>约束,要求参数类型T必须是整数类型。如果传入的参数类型不满足这个条件,编译器会报错。

2. requires-expression用法

requires-expression用于定义一个更复杂的要求,可以在概念定义或模板内部使用。

示例二:定义一个概念

#include <iostream>
#include <type_traits>

template <typename T>
concept Addable = requires(T a, T b) {
    { a + b } -> std::same_as<T>;
};

template <Addable T>
T add(T a, T b) {
    return a + b;
}

int main() {
    std::cout << add(1, 2) << std::endl;           // 输出:3
    std::cout << add(1.5, 2.5) << std::endl;       // 输出:4.0
    // std::cout << add(std::string("Hello, "), std::string("world!")) << std::endl; // 输出:Hello, world!
    return 0;
}

在这个示例中,我们定义了一个名为Addable的概念,该概念要求类型T必须支持+操作且结果类型与T相同。然后,我们使用这个概念来约束add函数模板的参数类型。

3. 组合多个条件

我们可以通过requires-expression组合多个条件,以定义更为复杂的概念。

示例三:组合条件

#include <iostream>
#include <concepts>
#include <type_traits>

template <typename T>
concept AddableAndIntegral = requires(T a, T b) {
    { a + b } -> std::same_as<T>;
    requires std::integral<T>;
};

template <AddableAndIntegral T>
T add(T a, T b) {
    return a + b;
}

int main() {
    std::cout << add(1, 2) << std::endl;           // 输出:3
    // std::cout << add(1.5, 2.5) << std::endl;    // 编译错误,double不满足std::integral
    return 0;
}

在这个示例中,我们定义了一个名为AddableAndIntegral的概念,该概念要求类型T既支持+操作,又是整数类型。

总结

C++20中的requires关键字为模板编程引入了一种强大的类型约束机制,使得模板函数和类的定义更加类型安全和可读。通过requires-clauserequires-expression,我们可以灵活地定义各种复杂的要求,确保模板参数符合预期。

希望通过本文的介绍,读者能够深入理解和应用requires关键字,以编写更为健壮和高效的C++代码。