c++20 Concepts的简写形式与requires 从句形式
在 C++20 Concepts 中,使用简写形式的 template<ConceptName T> 与使用完整形式的 template<typename T> requires ConceptName<T> 是等价的。以下是两种写法的具体转换:原始写法(简写形式)
template<typename T>
concept Arithmetic = std::is_arithmetic_v<T>;
template<Arithmetic T>// 简写形式
T add(T a, T b) { return a + b; }
等效写法(requires 从句形式)
template<typename T>
concept Arithmetic = std::is_arithmetic_v<T>;
template<typename T> // 完整形式
requires Arithmetic<T>// requires 从句
T add(T a, T b) { return a + b; }
关键区别说明:
特性简写形式requires 从句形式语法布局template<ConceptName T>template<typename T> requires ...可组合性只能指定单个 Concept可通过逻辑运算符组合多个束缚束缚表达式位置模板参数声明中模板参数列表后的 requires 从句中实用场景简单束缚复杂束缚(必要组合多个条件时) 组合多个束缚的示例:
template<typename T>
concept Signed = std::is_signed_v<T>;
template<typename T>
requires Arithmetic<T> && Signed<T>// 组合两个约束
T negative(T value) {
return -value;
}
negative(5); // OK
negative(3.14);// OK
negative("123"); // 错误:不满足 Arithmetic 约束
negative(2u); // 错误:unsigned 不满足 Signed 约束
两种形式的编译效果:
[*] 错误信息对比:
add("hello", "world");// 错误信息中会明确显示:
// 简写形式:"constraints not satisfied for 'T'"
// requires 从句形式:"constraint 'Arithmetic<T>' was not satisfied"
[*] 元编程特性保留:
template<Arithmetic T> // 两种形式均可配合
struct Calculator { // SFINAE、if constexpr 等特性
static_assert(Signed<T>);
};
更复杂的束缚示例:
template<typename T>
concept Printable = requires(std::ostream& os, T val) {
{ os << val } -> std::same_as<std::ostream&>;
};
template<typename T>
requires Arithmetic<T> && Printable<T>
void print_sum(T a, T b) {
std::cout << (a + b) << "\n";
}
print_sum(3, 5); // OK:int 是算术类型且可打印
print_sum(2.71, 3); // OK:double 符合条件
print_sum(true, false); // 错误:bool 是算术类型但不符合 Printable(需要重载<<)
尺度库风格的束缚:
template<typename T>
concept Addable = requires(T a, T b) {
{ a + b } -> std::convertible_to<T>;
};
template<typename T>
requires Addable<T>// 替代 C++17 的 std::void_t 技巧
T sum(T a, T b) { return a + b; }
建议:当束缚条件简单时使用简写形式,必要组合多个束缚或必要更清晰的错误信息时使用 requires 从句形式。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]