can one use templated begin/end methods in range based for loops

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.

see also compiler-explorer

Nat*_*ica 7

您将需要一个包装容器的适配器,并提供所需的迭代器。那会给你像

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)