正在将指针转换为范围
Converting a pointer to a range
这很有效:
const char* foo[] = {"This", "is", nullptr, "great"};
for (auto e : ::std::ranges::take_while_view (foo, // <- array
([](const char* s){return s!=nullptr;})))
std::cout << e << "n";
这不是:
const char* foo[] = {"This", "is", nullptr, "great"};
for (auto e : ::std::ranges::take_while_view (&foo[0], // <- pointer
([](const char* s){return s!=nullptr;})))
std::cout << e << "n";
error: no matching function for call to ‘take_while_view(const char**,
main(int, char**)::<lambda(const char*)>)’
我们是否可以使用标准库类型和函数,强制C++将指针视为一种半无限范围,然后我们可以进一步限制它?
我总是可以创建自己的类来表示半无限视图,但我宁愿在标准库中找到解决方案。
有一种方法可以从不同的部分组装这样一个范围,但不能隐式地将T*
视为一个。
您要做的是使用unreachable_sentinel_t
作为sentinel类型,从指针构造一个subrange
。所以你可以将这样一个函数编码为:
template<typename T>
auto inf_ptr_range(T *ptr)
{
return std::ranges::subrange(ptr, std::unreachable_sentinel_t{});
}
你可以在你的代码中使用它:
const char* foo[] = {"This", "is", nullptr, "great"};
for (auto e : ::std::ranges::take_while_view (
inf_ptr_range(foo),
([](const char* s){return s!=nullptr;})))
std::cout << e << "n";
或者使用视图样式表示法:
int main()
{
const char* foo[] = {"This", "is", nullptr, "great"};
for (auto e : inf_ptr_range(foo) | std::views::take_while(
[](const char* s){return s!=nullptr;}))
std::cout << e << "n";
}
使用iota
制作无限范围,然后将其切断。
auto my_range =
std::views::iota(&foo[0])
| std::views::transform([](auto p) -> auto& { return *p; })
| std::views::take_while([](auto p) { return p != nullptr; });
for(auto &ptr : my_range) {
std::cout << ptr << "n";
ptr = "really";
}
for(auto &ptr : my_range) std::cout << ptr << "n"; // mutation works!
std::cout << foo[3] << "n";
Godbolt
我相信这是安全的(take_while
"保护"transform
和iota
,这样我们就永远不会试图计算&foo[0] + 5
,甚至访问foo[3]
(。
相关文章:
- 正在将指针转换为范围
- std::map, std::unordered_map - 缩小初始值设定项列表中的转换范围
- 字符串的矢量并使用 C++20 范围进行转换
- 如何使用按位运算将随机uint64_t转换为范围 (0, 1) 的随机双精度
- 正在尝试确定转换后的范围是否为空
- 从转换后的范围构建新容器
- 为什么 gcc 警告只针对统一初始化缩小转换范围?
- std::vector 范围构造函数可以调用显式转换吗?
- 标准是否阻止在可变参数模板中使用足够小的文本值缩小文本转换范围
- 使用范围 v3 进行转换
- 从'::size_t'转换为'int'需要缩小转换范围
- C++ 提升范围:any_range和转换适配器
- 列表初始化时需要缩小转换范围
- C 范围V3:试图将链条链在一起转换
- 是否有范围::视图::转换的可修改视图版本
- 使用 atan2 将范围从 - 1 到 1 转换为度
- 从'double'转换为'int'需要缩小转换范围
- 正在缩小MSVC中到布尔警告的转换范围
- 更快的方法将数字从范围转换为另一个范围
- 使用boost范围转换适配器具有二进制功能