强制在基于范围的内容中使用cbegin()/ cend()

use*_*108 31 c++

这个问题涉及:

我什么时候应该使用新的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)

  • @Yola`constexpr`意味着它可以在常量表达式中使用,但这并不意味着它不能改变. (2认同)

Pet*_*ood 12

const auto& const_container = container;

for (const auto& v: const_container ) {
Run Code Online (Sandbox Code Playgroud)

  • `Type`拼写为'auto`? (3认同)

And*_*mek 9

基于范围的 for 循环从不使用cbegin()or cend()。(所以没办法强制。)相反的传闻出奇的多;有些人相信cbegin()andcend()被使用,但永远不要尝试相同的代码是否会在没有begin()and 的情况下编译end()。下面是一个简单的例子。据推测,仅beginend将被打印出来,无论多么很多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)

  • 不它不是。仅仅是因为你可以自由地提供一个完全不同形式的 `begin()` 的 `cbegin()` 实现,如果你决定的话。我的答案的关键点:原始问题基于错误的假设,即基于范围的 `for` 循环在某些条件下调用 `cbegin()` 或 `cend()`。事实上它没有。就这样。 (2认同)