C++20 概念(Concepts) 示例代码
以下是一些示例代码,展示了如何在 C++20 中定义和使用概念(Concepts)。
1. 定义概念
定义一个概念,要求类型必须支持加法操作,并且加法的结果能够转换为指定的类型。
#include <iostream>
#include <concepts>
// 定义一个概念,要求类型 T 支持加法操作
template <typename T>
concept Addable = requires(T a, T b) {
{ a + b } -> std::convertible_to<T>;
};
// 测试概念
void testConcept() {
std::cout << std::boolalpha;
std::cout << "int: " << Addable<int> << std::endl; // true
std::cout << "double: " << Addable<double> << std::endl; // true
std::cout << "std::string: " << Addable<std::string> << std::endl; // false
}
int main() {
testConcept();
return 0;
}
2. 使用概念约束模板
使用定义的概念约束模板,使模板只能接受符合概念要求的类型。
#include <iostream>
#include <concepts>
// 定义一个概念,要求类型 T 支持加法操作
template <typename T>
concept Addable = requires(T a, T b) {
{ a + b } -> std::convertible_to<T>;
};
// 使用概念约束模板
template <Addable T>
T add(T a, T b) {
return a + b;
}
int main() {
std::cout << add(5, 3) << std::endl; // 合法,int 满足 Addable 概念
// std::cout << add("hello", "world") << std::endl; // 不合法,const char* 不满足 Addable 概念
return 0;
}
3. 概念的组合
组合多个概念,以创建更复杂的类型要求。
#include <iostream>
#include <concepts>
// 定义一个概念,要求类型 T 支持加法操作
template <typename T>
concept Addable = requires(T a, T b) {
{ a + b } -> std::convertible_to<T>;
};
// 定义一个概念,要求类型 T 支持减法操作
template <typename T>
concept Subtractable = requires(T a, T b) {
{ a - b } -> std::convertible_to<T>;
};
// 定义一个组合概念,要求类型 T 既支持加法又支持减法
template <typename T>
concept Arithmetic = Addable<T> && Subtractable<T>;
// 使用组合概念约束模板
template <Arithmetic T>
T compute(T a, T b) {
return a + b - b; // 示例操作
}
int main() {
std::cout << compute(10, 5) << std::endl; // 合法,int 满足 Arithmetic 概念
// std::cout << compute("hello", "world") << std::endl; // 不合法,const char* 不满足 Arithmetic 概念
return 0;
}
4. 概念与类模板
将概念应用于类模板参数。
#include <iostream>
#include <concepts>
// 定义一个概念,要求类型 T 支持加法操作
template <typename T>
concept Addable = requires(T a, T b) {
{ a + b } -> std::convertible_to<T>;
};
// 使用概念约束类模板
template <Addable T>
class Adder {
public:
Adder(T x, T y) : a(x), b(y) {}
T add() const {
return a + b;
}
private:
T a, b;
};
int main() {
Adder<int> intAdder(5, 3);
std::cout << intAdder.add() << std::endl; // 合法,int 满足 Addable 概念
// Adder<std::string> strAdder("hello", "world"); // 不合法,std::string 不满足 Addable 概念
return 0;
}
5. 概念与函数重载
通过概念实现函数重载。
#include <iostream>
#include <concepts>
// 定义一个概念,要求类型 T 支持输出到流
template <typename T>
concept Printable = requires(T a, std::ostream& os) {
{ os << a } -> std::convertible_to<std::ostream&>;
};
// 定义两个重载函数,分别处理可打印和不可打印的类型
template <Printable T>
void print(const T& value) {
std::cout << "Printable: " << value << std::endl;
}
template <typename T>
void print(const T&) {
std::cout << "Non-printable" << std::endl;
}
int main() {
print(42); // 输出:Printable: 42
print("hello"); // 输出:Printable: hello
print(std::vector<int>()); // 输出:Non-printable
return 0;
}
这些示例展示了如何在 C++20 中定义和使用概念(Concepts)。概念为模板编程引入了更加直观的类型约束机制,使得代码更具可读性和可维护性。