【C++编程】requires用法

requires关键字

requires 子句(clause):用于指定模板参数必须满足的约束条件:

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

这也可以写成简化形式:

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

C++20引入了概念(Concepts)后,允许直接将概念名称作为模板参数的约束:

// C++20的新写法
template<Iterable Container>
void printFirstElement(const Container& c) { /*...*/ }

这种写法是一种语法糖,它等价于:

template<typename Container>
    requires Iterable<Container>
void printFirstElement(const Container& c) { /*...*/ }
#include <iostream>
#include <concepts>
#include <string>

// 定义一个概念:类型必须支持加法操作
template<typename T>
concept Addable = requires(T a, T b) {
    { a + b };  // 简单需求:检查表达式a + b是否有效
};

// 使用概念约束的函数模板
template<Addable T>
T add(T a, T b) {
    return a + b;
}

int main() {
    // 可以加法的类型
    std::cout << add(5, 3) << std::endl;                  // 整数加法
    std::cout << add(3.14, 2.71) << std::endl;            // 浮点数加法
    std::cout << add(std::string("Hello "), std::string("World")) << std::endl;  // 字符串加法
    
    // 以下代码会在编译期失败,因为自定义类型没有实现加法运算符
    /*
    struct NoAdd {};
    NoAdd a, b;
    add(a, b);  // 编译错误:NoAdd类型不满足Addable概念
    */
    
    return 0;
}

 

requires 与 auto 组合:C++20 还引入了"缩写函数模板"语法,可以将 requiresauto 结合使用:

// 传统写法
template<typename T>
    requires std::integral<T>
T gcd(T a, T b) {
    if (b == 0) return a;
    return gcd(b, a % b);
}

// 使用auto的简化写法
auto gcd(std::integral auto a, std::integral auto b) {
    if (b == 0) return a;
    return gcd(b, a % b);
}

 

posted @ 2025-04-26 11:13  苏格拉底的落泪  阅读(135)  评论(0)    收藏  举报