c++ - 可以在基于范围的 for 循环中使用模板化的开始/结束方法吗

标签 c++ for-loop templates

我处理一个类,该类应该在基于范围的 for 循环中进行迭代,因此它定义了一个迭代器类、开始方法和结束方法。现在,在我正在处理的示例中,这三个都是模板化的(我有这个最小的示例,其中模板参数并没有真正的意义,只是具有模板化的开始和结束):

#include <cstddef>
#include <tuple>
#include <vector>

struct Iterable {
  using Widget = std::tuple<int, float>;
  template <typename access_type>
  struct Iterator {
    Iterable*   m_iterable;
    std::size_t m_pos;
    bool        operator==( const Iterator& other ) { return m_iterable == other.m_iterable && m_pos == other.m_pos; }
    bool        operator!=( const Iterator& other ) { return !( this->operator==( other ) ); }
    access_type operator*() {
      Widget tmp = m_iterable->m_storage[m_pos];
      return std::get<access_type>( tmp );
    }
    Iterator operator++() {
      m_pos++;
      return *this;
    }
  };
  template <typename access_type = int>
  Iterator<access_type> begin() {
    return {this, 0};
  }
  template <typename access_type = int>
  Iterator<access_type> end() {
    return {this, m_storage.size()};
  }
  std::vector<Widget> m_storage;
};

现在这个可迭代对象在基于范围的 for 循环中工作

Iterable container;
for (auto element: container) { … }

这使用begin<int>end<int>cppinsights 可以看出(注意基于范围的循环版本中迭代器的类型)。

我不清楚的是,除了退回到 c++11 之前的循环之外,还有其他方法可以指定 for 循环的模板参数吗?

for (auto iter = container.begin<float>(); iter != container.end<float>(); ++iter) { … }

编辑以澄清讨论范围。可迭代类被认为是预先存在于上游代码中的,我不想讨论将其放入世界中的原因。别人的代码已经存在,我必须处理它。

see also compiler-explorer

最佳答案

您需要的是一个包装容器并提供您希望它具有的迭代器的适配器。这会给你一个类似的类(class)

template<typename T>
struct Adapter
{
    Iterable & it;
    Adapter(Iterable& it) : it(it) {}
    auto begin() 
    {
        return it.begin<T>();
    }
    auto end() 
    {
        return it.end<T>();
    }  
};

你会像这样使用它

int main()
{
    Iterable container;
    for ( auto element : Adapter<float>{container} ) 
    { 
        static_assert( std::is_same_v<decltype( element ), float> );
    }
}

关于c++ - 可以在基于范围的 for 循环中使用模板化的开始/结束方法吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58396082/

相关文章:

java - 使用JAVA进行循环控制

c++ - 为什么模板模板参数不允许在参数列表后出现 'typename'

C++ vector 不更新

C++使用参数在数组中分配和构造对象

c++ - 使用 Opengl 绘制超过 50k 球体时如何提高速度

javascript - for循环后未到达代码(javascript)

batch-file - .bat 无意中删除子目录

c++ - c++,将enable_if与现有模板类一起使用?

c++ - 有没有让我们将 "pass a namespace"放入模板的技巧?

c++ - 在 DirectDrawCreate 上解析 'LNK2019 unresolved external symbol'