在基于范围的for中强制使用cbegin()/cend()
forcing use of cbegin()/cend() in range-based for
这个问题指的是:
我什么时候应该使用新的range -for,我可以将它与新的cbegin/cend结合使用吗?
根据这个问题,要强制使用cbegin()
和cend()
,需要这样做,例如:
for (auto& v: const_cast<decltype(container) const>(container))
对于一个应该消除它的结构来说,这是大量的样板代码。有没有更紧凑的方法?我的问题的原因是,隐式共享容器可能会把我使用begin()
作为分离自身的线索。
更新:std::as_const
将在c++ 17中,在<utility>
头中。
在c++ 17之前,它没有内置语法;但是,您可以轻松地编写一个方便的包装器:
template<typename T> constexpr const T &as_const(T &t) noexcept { return t; }
for (auto &v: as_const(container))
注意,这调用begin() const
而不是cbegin()
;标准容器通用要求指定cbegin()
和begin() const
的行为相同。
如果容器对非const迭代进行了特殊处理,则它本身有一个成员函数可能是有意义的:
const Container &crange() const noexcept { return *this; }
for (auto &v: container.crange())
基于范围的for循环从不使用cbegin()
或cend()
。(因此没有办法强迫它。)令人惊讶的是,有许多谣言与之相反;有些人认为使用了cbegin()
和cend()
,但从未尝试过没有begin()
和end()
是否可以编译相同的代码。下面是一个简单的例子。假设,无论添加多少个const_cast
,只会打印出begin
和end
。
#include <iostream>
class Iterable {
struct Iterator {
bool operator !=(const Iterator &) { return false; }
int operator *(){ return 0; }
Iterator& operator ++() { return *this; }
};
public:
Iterator cbegin() const noexcept {
std::cout << "cbegin" << std::endl;
return Iterator{};
}
Iterator cend() const noexcept {
std::cout << "cend" << std::endl;
return Iterator{};
}
Iterator begin() const noexcept {
std::cout << "begin" << std::endl;
return Iterator{};
}
Iterator end() const noexcept {
std::cout << "end" << std::endl;
return Iterator{};
}
};
int main() {
Iterable a;
const Iterable b;
for (auto i : a) {}
for (auto i : b) {}
for (const auto &i : a) {}
for (const auto &i : b) {}
return 0;
}
const auto& const_container = container;
for (const auto& v: const_container ) {
相关文章:
- 为什么 std::span 缺少 cbegin 和 cend 方法?
- begin() 在 C++17 年被制作为 constexpr 但在 C++14 年成为 cbegin() 吗?
- 如何实现 cbegin() 和 cend() 从 begin() 和 end() ?
- 在载体中使用cbegin和cend
- 无法在 cbegin 中定义initializer_list
- begin(),end()和cbegin(),cend()之间的区别是什么?
- 是cbegin/Cend不足以使循环范围
- 为什么 std::cbegin() 不调用容器上的 .cbegin()?
- 'cbegin'未在此范围内声明
- std::cbegin()除了begin()之外还有其他内容吗
- 为什么std::cbegin返回与std::begin相同的类型
- cbegin/cend背后的原因是什么
- 非成员函数 begin()/cbegin() 及其 constexpr-ness
- 为什么我不能将 cend() 和 cbegin() 传递给count_if?
- gcc支持cbegin和cend方法
- cbegin()/cend() vs constBegin()/constEnd()
- 为什么 g++ 声明某些 valarray o 存在"no matching function for call cbegin(o)"<double>?
- 在基于范围的for中强制使用cbegin()/cend()
- 我应该在什么时候使用新的range -for,以及我可以将它与新的cbegin/cend结合使用吗?
- 既然有了cbegin(), cend(),为什么没有cfront(), cback(), cfind(),…