现代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++中用于指定模板参数的约束,提高代码的可读性、健壮性和易用性。概念为模板编程提供了更清晰的语义和更强的类型检查。