现代C++(特别是C++20及以后的版本)引入了概念(Concepts),这是一种指定模板参数必须满足的约束的方式。概念使得模板代码更清晰,更容易理解和使用,并且能在编译时提供更好的错误信息。以下是C++概念的关键特性和使用示例:
1. 基本概念使用
概念定义了模板参数必须满足的一组约束。
#include <concepts>
#include <iostream>
template<typename T>
requires std::integral<T> // 基本概念
T add(T a, T b) {
return a + b;
}
void basicConcept() {
std::cout << add(1, 2) << std::endl; // 正确
// std::cout << add(1.1, 2.2) << std::endl; // 错误,浮点数不满足std::integral概念
}
2. 自定义概念
你可以定义自己的概念,以表达更复杂的约束。
#include <iostream>
template<typename T>
concept Addable = requires(T a, T b) {
{ a + b } -> std::convertible_to<T>;
};
template<typename T>
requires Addable<T> // 使用自定义概念
T add(T a, T b) {
return a + b;
}
void customConcept() {
std::cout << add(3, 4) << std::endl; // 正确
}
3. 概念与函数重载
概念可以与函数重载一起使用,让编译器根据概念选择合适的函数版本。
#include <iostream>
#include <concepts>
template<typename T>
requires std::integral<T>
void process(T value) {
std::cout << "Processing integral: " << value << std::endl;
}
template<typename T>
requires std::floating_point<T>
void process(T value) {
std::cout << "Processing floating point: " << value << std::endl;
}
void conceptWithOverloading() {
process(10); // 调用处理整数的版本
process(10.5); // 调用处理浮点数的版本
}
4. 概念在类模板中的应用
概念同样可以用在类模板的定义中,限制模板参数的类型。
#include <iostream>
#include <vector>
#include <concepts>
template<typename T>
requires std::integral<T>
class Numbers {
std::vector<T> values;
public:
void add(T value) {
values.push_back(value);
}
void print() {
for (auto v : values) {
std::cout << v << " ";
}
std::cout << std::endl;
}
};
void conceptInClassTemplate() {
Numbers<int> numbers;
numbers.add(1);
numbers.add(2);
numbers.print(); // 输出:1 2
// Numbers<double> decimals; // 错误,double不满足std::integral概念
}
通过这些示例可以看到概念如何在现代C++中用于指定模板参数的约束,提高代码的可读性、健壮性和易用性。概念为模板编程提供了更清晰的语义和更强的类型检查。