Ale*_*ara 19 c++ c++-concepts c++20
C++20 引入了概念,这是一种对模板函数或类可以采用的类型施加约束的智能方法。
虽然迭代器类别和属性保持不变,但改变的是执行它们的方式:C++17 之前使用标记,C++20 以来使用概念。例如,您可以使用 std::forward_iterator 概念来标记迭代器,而不是使用 std::forward_iterator_tag 标签。
同样的事情也适用于所有迭代器属性。例如,前向迭代器必须是 std::incrementable。这种新机制有助于获得更好的迭代器定义,并使编译器中的错误更具可读性。
这段文字摘自这篇文章: https ://www.internalpointers.com/post/writing-custom-iterators-modern-cpp
但作者并没有升级如何用概念在C++20上制作自定义迭代器的内容,仍然是<= C++17标签版本。
有人可以举例说明如何使用概念功能在 C++20 版本中为自定义容器编写自定义迭代器吗?
小智 12
总的来说,C++20 定义迭代器的方式不需要显式标记类型,而是依赖于概念来检查给定类型是否恰好符合迭代器类别的要求。
这意味着您现在可以安全地通过鸭子类型获得胜利,同时支持干净的重载解析和错误消息:
struct my_iterator {
// No need for tagging or anything special, just implement the required interface.
};
Run Code Online (Sandbox Code Playgroud)
如果您想确保给定类型满足特定迭代器类别的要求,则需要了解static_assert该类型的概念:
#include <iterator>
static_assert(std::forward_iterator<my_iterator>);
Run Code Online (Sandbox Code Playgroud)
通过使用模板参数中的概念来强制函数仅接受特定的迭代器类别。
#include <iterator>
template<std::forward_iterator Ite, std::sentinel_for<Ite> Sen>
void my_algorithm(Ite begin, Sen end) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
std::sentinel_for<>现在用于结束迭代器而不是使用Ite两次。它允许有选择地为结束迭代器使用单独的类型,这有时很方便,特别是对于输入迭代器。
例如:
struct end_of_stream_t {};
constexpr end_of_stream_t end_of_stream{};
struct my_input_iterator {
// N.B. Not a complete implementation, just demonstrating sentinels.
some_stream_type* data_stream;
bool operator==(end_of_stream_t) const { return data_stream->empty(); }
};
template<std::input_iterator Ite, std::sentinel_for<Ite> Sen>
void my_algorithm(Ite begin, Sen end) {
while(begin != end) {
//...
}
}
void foo(some_stream_type& stream) {
my_algorithm(my_input_iterator{&stream}, end_of_stream);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5417 次 |
| 最近记录: |