这个问题涉及:
我什么时候应该使用新的ranged-for,我可以将它与新的cbegin/cend结合使用吗?
基于这个问题,强制使用cbegin()
和cend()
需要做的,例如:
for (auto& v: const_cast<decltype(container) const>(container))
Run Code Online (Sandbox Code Playgroud)
这是一个应该消除它的构造的很多样板代码.有更紧凑的方法吗?我的问题的原因是,隐式共享容器可能会将我的使用begin()
作为分离自己的线索.
eca*_*mur 28
更新:std::as_const
将在<utility>
标题中的C++ 17中.
在C++ 17之前,它没有内置的语法; 但是,您可以轻松编写便利包装器:
template<typename T> constexpr const T &as_const(T &t) noexcept { return t; }
for (auto &v: as_const(container))
Run Code Online (Sandbox Code Playgroud)
请注意,这是调用begin() const
而不是cbegin()
具体; 该标准的容器一般要求规定,cbegin()
和begin() const
相同的行为.
如果你的容器特别处理非常量迭代,那么它本身就有一个成员函数:
const Container &crange() const noexcept { return *this; }
for (auto &v: container.crange())
Run Code Online (Sandbox Code Playgroud)
Pet*_*ood 12
const auto& const_container = container;
for (const auto& v: const_container ) {
Run Code Online (Sandbox Code Playgroud)
基于范围的 for 循环从不使用cbegin()
or cend()
。(所以没办法强制。)相反的传闻出奇的多;有些人相信cbegin()
andcend()
被使用,但永远不要尝试相同的代码是否会在没有begin()
and 的情况下编译end()
。下面是一个简单的例子。据推测,仅begin
与end
将被打印出来,无论多么很多const_cast
中追加。
#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;
}
Run Code Online (Sandbox Code Playgroud)