Why do C++ function objects need reference type member variables?

c++, function-object

Solution

(1) Why does it fail to compile when count is a regular variable not a reference type?

This is a very interesting question. The question should be rather, why the code compiles when `count` is declared as a reference. :)

The regular variable fails because `int count` is not modifiable inside a `const` qualified function `operator()(int &i) const;`.

References are little different. In your code you are declaring the method as `const`, which means that `count` which is referring to `i`, now cannot refer to anything else. But that's anyway not possible due to nature of references :). One cannot change reference binding after the initialization. `operator()` just checks whether you are changing the binding of `count` to anything else or not? And the answer is always no. Because `count++` changes the value referred by `count` and not the binding.

In your code, it doesn't matter if a member method is `const` or not when it comes to `int& count`.

Relate `int& count;` to `int* const p_count;` and try to simulate the situation on your own.

(2) Why does it fail to compile it I change the ctor to the following? `CountFrom(int &n) { count = n; }`

Because reference must be assigned to a variable while initialization. In simple example;

int i, &r;  // error, because 'r' not initialized
r = i;  // this is not initialization but a copy

On a side note, you should be extra careful when you are dealing with reference variables inside a `class`. Because it's easy to mess up with their scope and validity. For example, here the validity of `count` is dependent on the scope of `i`.

Edit: After your 2nd edit, it's very trivial to know why that version works. Because `count` is now a simple variable. It can be skipped from initialization in the initializer list of the constructor unlike reference. Moreover the `const` correctness of the `operator()` is gone, so any member variable of the `class` can now be modified inside it.

You should choose a `const` version of the member method, if you want to state that no `class` member "must" change inside it (unless any variable is `mutable` or you use `const_cast`). In all other cases use the normal version of the member method. They both can co-exist as well depending on your business logic. This is a bit of a broad question and it's worth to have another thread for this.

Problem

This is a newbie C++ question. I was reading the "Function object" article in Wikipedia. The article has an example in C++ similar to the following: ``` struct printClass { int &count; printClass(int &n) : count(n) {} void operator()(int &i) const { count++; cout << i << "[" << count << "] "; } }; int main(int argc, char** argv) { vector<int> a(5, 7); a[4] = -1; a.resize(10, 3); int state = 0; for_each(a.rbegin(), a.rend(), printClass(state)); } ``` I have 2 questions: Why does it fail to compile when count is a regular variable not a reference type? Demo Why does it fail to compile it I change the `ctor` to the following? Demo `printClass(int &n) { count = n; }` Thanks. EDIT: Thanks for explaining. I see that the following version works, too. Is there a reason for chosing one over another? ``` struct printClass { int count; printClass(int n) { count = n; } void operator()(int &i) { count++; cout << i << "[" << count << "] "; } }; ``` EDIT: Based on iammilind's reply, here is the 3rd version that works too using `const_cast<int &>`. ``` struct printClass { int count ; printClass(int n) : count(n) {} void operator()(int &i) const { const_cast<int &>(count)++; cout << i << "[" << count << "] "; } }; ```

Original source