forcing use of cbegin()/cend() in range-based for

前端 未结 3 756

This question refers to:

When should I use the new ranged-for and can I combine it with the new cbegin/cend?

Based on that question, to force the use of

相关标签:
3条回答
  • 2020-12-06 04:31

    Update: std::as_const will be in C++17, in the <utility> header.

    Prior to C++17, there's no built-in syntax for it; however, you can easily write a convenience wrapper:

    template<typename T> constexpr const T &as_const(T &t) noexcept { return t; }
    for (auto &v: as_const(container))
    

    Note that this calls begin() const rather than cbegin() specifically; the Standard container general requirements specify that cbegin() and begin() const behave identically.

    If your container treats non-const iteration specially, it might make sense for it itself to have a member function:

    const Container &crange() const noexcept { return *this; }
    for (auto &v: container.crange())
    
    0 讨论(0)
  • 2020-12-06 04:32

    The range-based for loop never uses cbegin() or cend(). (Therefore there is no way to force it.) There are surprisingly many rumors to the contrary; some believe that cbegin() and cend() are used, but never try whether the same code would compile without begin() and end(). A trivial example follows. Presumably, only begin and end will be printed out, no matter how many const_casts are added.

    #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;
    }
    
    0 讨论(0)
  • 2020-12-06 04:37
    const auto& const_container = container;
    
    for (const auto& v: const_container ) {
    
    0 讨论(0)
提交回复
热议问题