c++ 模版编程里面,经常有这样的场景, 我们需要对类型进行限制, 即他需要支持一系列操作才行,在c++20 前为了实现这些,我们很可能会写出一些非常晦涩难懂的代码 但是c++20 concept 将这一切都变得非常容易
本文定义了个LoopAble, 只有符合其定义的约束是时候才能通过编译,
#include <iostream>
#include <vector>
using namespace std;
// 是否支持 inplace loop for
template <typename T>
concept LoopAble = requires(T t) {
// t 有begin()函数 且能 前++, 注意operator++(int) 是后++
// 约束 1
++t.begin();
// t.begin() 的类型支持 *
// 约束 2
*(t.begin());
// t 有end函数
// 约束 3
t.end();
// t.begin() 的类型 支持 !=
// 约束 4
t.begin() != t.end();
};
// 打印值
// T 支持LoopAble
template <LoopAble T>
void pt(const T& t) {
for (auto v : t) {
cout << v << "\t";
}
cout << endl;
}
// 自定义迭代器
template <typename T>
class Ite {
private:
T* val;
public:
Ite(T* val) : val(val) {}
T operator*() { return *val; }
Ite operator++() {
val++;
return *this;
}
bool operator!=(Ite other) { return val != other.val; }
};
// 自定义容器
template <typename T>
class MyVec {
private:
T* data;
int size;
public:
MyVec(vector<T> data) {
size = data.size();
this->data = new T[size];
for (int i = 0; i < size; i++) {
this->data[i] = data[i];
}
}
~MyVec() { delete[] data; }
Ite<T> begin() const { return Ite<T>(data); }
Ite<T> end() const { return Ite<T>(data + size); }
};
int main() {
vector<int> vec{1, 2, 3, 4};
pt(vec);
// 自定义容器
// 尝试 注释 自定义容器和迭代器中的函数, 会发现, 如果不支持LoopAble任意一个函数, 编译就会不通过
vector<int> vec2{1, 2, 3, 4, 5, 6, 7};
MyVec<int> myVec(vec2);
pt(myVec);
}