pse*_*ert 2 c++ templates for-loop
I deal with a class that is meant to be iterable in range based for loops, so it defines an iterator class, begin- and end-method. Now in the example I'm working on, these three are templated (I have this minimal example, where the template parameter isn't really meaningful but just has templated begin and end):
#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;
};
Run Code Online (Sandbox Code Playgroud)
Now this iterable works in a range based for loop
Iterable container;
for (auto element: container) { … }
Run Code Online (Sandbox Code Playgroud)
This uses begin<int>
and end<int>
as is somewhat visible from cppinsights (note the type of the iterator in the range based version of the loop).
What is not clear to me is, is there a way to specify the template parameters for the for loop other than retreating to a pre-c++11 loop?
for (auto iter = container.begin<float>(); iter != container.end<float>(); ++iter) { … }
Run Code Online (Sandbox Code Playgroud)
EDIT to clarify the scope of the discussion. The iterable class is considered to be preexisting in upstream code, I don't want to discuss the reasons for putting it into the world. Someone else's code just exist and I have to deal with it.
您将需要一个包装容器的适配器,并提供所需的迭代器。那会给你像
template<typename T>
struct Adapter
{
Iterable & it;
Adapter(Iterable& it) : it(it) {}
auto begin()
{
return it.begin<T>();
}
auto end()
{
return it.end<T>();
}
};
Run Code Online (Sandbox Code Playgroud)
你会用它像
int main()
{
Iterable container;
for ( auto element : Adapter<float>{container} )
{
static_assert( std::is_same_v<decltype( element ), float> );
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
59 次 |
最近记录: |