C++20 concepts:把模板要求写在入口,而不是等一屏报错

C++20 concepts:把模板要求写在入口,而不是等一屏报错

模板函数若只能接收特定类型,最好直接表达这个要求。concepts 让约束成为接口的一部分,调用错误通常也能更早定位到"不满足什么条件"。

最低标准:C++20。示例分别约束整数类型和可求 size 的对象。

1. 命名约束,让调用意图可读

cpp 复制代码
#include <concepts>
#include <cstddef>
#include <iostream>
#include <string>
#include <type_traits>

template<class T>
concept NonBoolIntegral = std::integral<T> &&
    (!std::same_as<std::remove_cv_t<T>, bool>);

template<NonBoolIntegral T>
constexpr bool is_even(T value) {
    return value % 2 == 0;
}

template<class T>
concept HasSize = requires(const T& value) {
    { value.size() } -> std::convertible_to<std::size_t>;
};

template<HasSize T>
void show_size(const T& value) {
    std::cout << value.size() << '\n';
}

int main() {
    static_assert(NonBoolIntegral<int>);
    static_assert(!NonBoolIntegral<bool>);
    std::cout << std::boolalpha << is_even(6) << '\n';
    show_size(std::string{"hello"});
}

输出是 true 和 5。is_even 不接受浮点数,也主动排除 bool;这是业务选择,而不是 std::integral 自带的限制。

2. requires 检查表达式是否适用

HasSize 表示:对 const 对象调用 size 的表达式合法,而且结果能够转换成 size_t。requires 表达式本身不会为了检查约束而执行这次调用。

注意 const 和引用限定的影响:如果某个类型只有非 const 的 size 成员,就不满足这里定义的 HasSize。约束应与函数实际使用对象的方式一致,不宜随意放宽。

3. 语法通过不代表业务一定正确

一个对象完全可以有返回错误数值的 size 函数,仍然通过上述表达式检查。类似地,比较器的调用形式符合要求,也不代表编译器能证明它满足严格弱序。

概念表达了可检查的结构要求,但业务语义、有效值范围、资源状态和线程安全仍然需要文档、运行时校验和测试。

4. 从小而明确的约束开始

尽量使用标准已有的概念,再按确实需要的能力组合。不要为了一个只会调用 size 的函数,要求参数必须拥有几十个无关成员;过度约束会排除本来可以工作的类型。

concepts 也不是类继承接口。一个类型不必显式声明"实现某个 concept",只要满足约束即可。它特别适合泛型算法、容器工具函数和库接口,能把隐含约定变成读者看得见的入口条件。

相关推荐
码匠许师傅9 小时前
【C++三方组件】Asio 下篇:C++20 协程版 TCP 客户端与服务端
c++·tcp/ip·c++20
啦啦啦啦啦zzzz17 天前
利用RAII机制进行日志的采集
linux·服务器·c++·网络编程·c++20
啦啦啦啦啦zzzz18 天前
Logger的组装(c++20)
c++·算法·c++20
啦啦啦啦啦zzzz20 天前
Appender抽象类的实现c++20
linux·服务器·c++·c++20
OPEN-F23 天前
C++20新特性精讲:概念、范围与三路比较
算法·c++20
小小龙学IT1 个月前
C++ std::chrono 时间库深度解析:从 duration 模板到 C++20 日历与时区
linux·c++·c++20
郝学胜-神的一滴1 个月前
C++20 高级编程 004:从初始化、内存到const系列关键字
开发语言·算法·编程·软件构建·c++20
可爱系程序猿1 个月前
msvcp120.dll 加载失败排查:VC++ 2013、进程架构与插件私有目录如何对应
程序人生·电脑·c++20
ShineWinsu1 个月前
对于C++:C++20中线程、初始化、Lambda与内存视图等特性的解析
c++·c++20