learning_dude
learning_dude

Reputation: 1050

Why is this const auto variable in a range-for loop compiling for a const member function of a class?

I have the following classes declaration, and according to what I've learned related to const member functions, const objects can not call non-const member functions. In the range-for loop, we are using "const auto animal", which is supposely using a const object, so I think that the const object should give a compile error when calling the non-const member function speak(), but it actually compiles, why?, maybe I dont have a clear idea of how the range-for loop really works... Thanks!

#include <iostream>
#include <string>

class Animal {
protected:
     std::string name_;
     std::string speak_;
public:
    Animal(const std::string &name, const std::string &speak) : name_(name), speak_(speak){}
    const std::string &getName() const  { return name_;}
    std::string speak()  { return speak_;}
};

class Cat : public Animal{
public:
 Cat(const std::string &name) : Animal(name, "meow"){}
};

class Dog : public Animal{
public:
 Dog( const std::string &name) : Animal(name, "woof"){}
};

int main() {
    Cat tom{ "tom" };
    Dog felix{ "felix" };

    Animal *animals[]{ &tom, &felix};
     for (const auto &animal : animals)
         std::cout << animal->getName() << " says " << animal->speak() << '\n';


    return 0;
}

Upvotes: 1

Views: 519

Answers (1)

N. Shead
N. Shead

Reputation: 3938

The const auto& here becomes a const reference to a variable of type Animal*. This means you can't change where the pointer points to, but the pointed-to value itself is still mutable.

Replacing auto would look like:

for (Animal* const& animal : animals)
  // ...

Upvotes: 6

Related Questions