C++ std::same_as概念定义及requires表达式单模板参数用法疑问
关于std::same_as的定义与requires表达式中用法的解答
核心问题解答
你提到的用法确实是C++标准规定的语法规则:
在requires表达式的复合要求(即{ 表达式 } -> 约束写法),以及模板参数的前置约束写法中,单参数形式的std::same_as<目标类型>是语法糖,编译器会自动把左侧表达式/模板参数的类型作为第一个模板参数传入,补全为双参数形式的std::same_as<推导得到的类型, 目标类型>。
具体规则细节
对于{ E } -> C<Args...>这类复合要求,编译器的处理逻辑是:
- 先计算表达式
E的类型,得到类型T = decltype((E)) - 将
T作为第一个实参传入后面的概念C,最终要求C<T, Args...>的结果为true
对应到你的代码示例:
requires { { func() } -> std::same_as<bool>; }
等价于完整的约束写法:
requires { requires std::same_as<decltype((func())), bool>; }
完全匹配std::same_as需要两个模板参数的定义。
std::same_as的实现说明
你看到的cppreference上的实现,做了两层校验detail::SameHelper<T,U> && detail::SameHelper<U,T>,是为了保证约束的对称性:std::same_as<T,U>和std::same_as<U,T>的结果永远一致,避免出现概念偏序的异常情况。
同类语法糖扩展
这种自动补全第一个模板参数的规则不止适用于requires表达式,也适用于模板的前置约束写法,比如:
// 写法1:前置约束 template <std::same_as<bool> T> void test(T t); // 等价于写法2:完整约束 template <typename T> requires std::same_as<T, bool> void test(T t);
内容的提问来源于stack exchange,提问作者Klaus
相关产品推荐
相关产品推荐

