c++20 Concepts的簡寫形式與requires 從句形式
- 原始寫法(簡寫形式)
- 等效寫法(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
從句形式。