简体   繁体   中英

What does range-for loop exactly do?

I'm working on a snake game program. I use a deque of Body in class Snake to represent a snake and of course Body is a struct I have defined. Here is part of the code:

struct Body {        // one part of snake body
    int x, y, direction;
    Body() : x(0), y(0), direction(UP) { }
    Body(int ix, int iy, int id) : x(ix), y(iy), direction(id) { }
};

class Snake {
protected:
    std::deque<Body> body;
    // other members
public:
    auto begin()->std::deque<Body>::const_iterator const { return body.cbegin(); }
    auto end()->std::deque<Body>::const_iterator const { return body.cend(); }
    // other members
};

And in another function construct_random_food I need to generate a food and make sure it does not coincide with the snake. Here's the function definition:

Food construct_random_food(int gameSize, const Snake& snake) {
    static std::random_device rd;
    static std::uniform_int_distribution<> u(2, gameSize + 1);
    static std::default_random_engine e(rd());
    Food f;
    while (1) {
        f.x = u(e) * 2 - 1;
        f.y = u(e);
        bool coincide = 0;
        for (const auto& bd : snake) // This causes an error.
            if (bd.x == f.x && bd.y == f.y) {
                coincide = 1; break;
            }
        if (!coincide) break;
    }
    return f;
}

An error is caused at the range-based for-loops line. It says that I'm trying to cast const Snake to Snake& (casting a low-level const away). I fix the problem by rewriting that line like this:

for (const auto& fd : const_cast<Snake&>(snake))

So I'm wondering what exactly a range-for do and what it needs. Does the error have anything to do with the begin() function in class Snake?

The problem is that your begin and end functions are not const.

auto begin()->std::deque<Body>::const_iterator const { return body.cbegin(); }
            // this applies to the return type ^^^^^

You've applied the const qualifier to the return type, not to the calling object. Put the const qualifier before the trailing return type.

auto begin() const ->std::deque<Body>::const_iterator { return body.cbegin(); }

You can see the correct order in which you should place function qualifiers here: http://en.cppreference.com/w/cpp/language/function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM