基于范围的 for 循环是否可以采用类型参数

Can a range-based for loop take a type argument?

本文关键字:是否 类型参数 循环 for 于范围 范围      更新时间:2023-10-16

据我所知,基于范围的 for 循环只能接受 c 样式数组、具有begin()end()定义成员函数的类型对象,或者可以使用 ADL 找到自由函数begin(Type)end(Type)Type类型的对象。

有没有办法让循环采用类型参数,以便编译这样的代码?

class StaticVec{
//shortened implementation
    static myIterator begin();
    static myIterator end();
};
void foo() {
    for(auto elem : StaticVec){
       dosomething(elem);
    }
}

我想省略在循环中编写StaticVec::values()的必要性。

作为一般解决方案,您可以定义

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(); }

然后你可以写例如

auto main() -> int
{
    for( auto elem : Static_collection<Static_vec>() )
    {
        std::cout << elem << ' ';
    }
    std::cout << 'n';
}

补遗:
然而,在大多数实际情况下,只需创建一个包含静态beginend成员函数的类实例就足够了,如 Jarod42 和 Matt McNabb 的答案所示(前者在我发布上述内容时已经发布),例如

for( auto const& elem : StaticVec() )
{
    // ...
}

如果创建实例可能会产生不良的副作用,现在或将来进行一些维护工作后,请使用通用解决方案。

否则,如果实例创建基本上是免费的,我会这样做。

您仍然可以(如果适用)构造一个虚拟对象:

for (auto&& elem : StaticVec{}) {
    // ...
}

这绝对是不可能的。示例中的范围变量是StaticVec(不是变量),因此它扩展的代码将涉及auto it = StaticVec.begin()auto it = begin(StaticVec),并且这些表达式都无效,函数调用需要对象而不是类型。

这是有效的,因为静态成员函数仍然可以通过.表示法调用:

#include <iostream>
using namespace std;
struct StaticVec
{
    typedef int *myIterator;
    static int x[5];
    static myIterator begin() { return x; }
    static myIterator end() { return x + 5; }
};
int StaticVec::x[5] = { 10, 20, 30, 40, 50 };
void dosomething(int i)
{
cout << i << endl;
}
int main() 
{
    for(auto elem : StaticVec())
    {
       dosomething(elem);
    }
}