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

时间:2014-12-16 10:27:16

标签: c++ c++11 for-loop static

据我所知,基于范围的for循环只能采用c风格的数组,类型的对象具有定义的成员函数begin()end(),或者是一个Type类型,可以使用ADL找到自由函数begin(Type)end(Type)

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

class StaticVec{
//shortened implementation
    static myIterator begin();
    static myIterator end();
};

void foo() {
    for(auto elem : StaticVec){
       dosomething(elem);
    }
}

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

4 个答案:

答案 0 :(得分:6)

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

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() )
{
    // ...
}

如果实例创建可能会产生不良副作用,现在或可能在未来维护工作之后,请使用常规解决方案。

否则,如果实例创建基本上是免费的,我会去那。

答案 1 :(得分:4)

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

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

答案 2 :(得分:3)

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

答案 3 :(得分:1)

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

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