From what I can tell, range-based for loops can only take a c-style array, an object of a type that has the member functions begin() and end() defined, or an object of a type Type for which the free functions begin(Type) and end(Type) can be found with ADL.
Is there a way to make the loop take a type argument, so code like this compiles?
class StaticVec{
//shortened implementation
static myIterator begin();
static myIterator end();
};
void foo() {
for(auto elem : StaticVec){
dosomething(elem);
}
}
I would like to omit the necessity of writing StaticVec::values() in the loop.
As a general solution you can define
template< class Type > struct Static_collection {};
template< class Type >
auto begin( Static_collection<Type> const& )
-> decltype( Type::begin() )
{ return Type::begin(); }
template< class Type >
auto end( Static_collection<Type> const& )
-> decltype( Type::end() )
{ return Type::end(); }
and then you can write e.g.
auto main() -> int
{
for( auto elem : Static_collection<Static_vec>() )
{
std::cout << elem << ' ';
}
std::cout << '\n';
}
Addendum:
In most practical cases it will however suffice to just create an instance of the class holding the static begin and end member functions, as shown in Jarod42’s and Matt McNabb’s answers (the former already posted when I posted the above), e.g.
for( auto const& elem : StaticVec() )
{
// ...
}
If instance creation can have undesirable side effects, now or perhaps after some future maintainance work, then use the general solution.
Otherwise, if instance creation is essentially free, I’d go for that.
You may still (if applicable) construct a dummy object:
for (auto&& elem : StaticVec{}) {
// ...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With