Nevermind, misread a bit of what Disch said. I believe that it has to do with the fact that temporary objects have no identifier and there's thus no way to change things in them directly, although I might be wrong on this.
// Some classes
class A
{
public:
A() { v = 0; }
int v;
};
class B
{
public:
B() { v = 0; }
B(const A& obj) { v = obj.v; }
int v;
};
// a function to add something to an object
void AddToV(B& b,int add)
{
b.v += add;
}
//====================
int main()
{
A a;
B b;
// add to v
AddToV(b,5);
cout << b.v; // prints 5 as you'd expect
// add to a's v
AddToV(a,5);
cout << a.v; // SURPRISE, a.v is still 0
// AddToV didn't change a's v, it changed the temporary nameless object's v
}
If temporary objects were non-const, the above would silently compile and not report any error, leaving you with quite a nasty bug. Obviously it doesn't seem very nasty in this example, but in a larger program it could be VERY hard to track something like that down.
Fortunately, C++ compilers will (or at least should) complain at the second AddToV call because of the temporary object creation involved in the function call, preventing you from making this mistake.
This jives with the unwritten rule that "objects passed by non-const reference are out parameters and can expected to be modified by the function". For any function that doesn't change the parameter, it should be passed by const reference instead.
EDIT:
Another reason is because it just flat out doesn't make sense with basic types:
1 2 3 4 5 6 7 8 9 10 11 12
void Plus5(int& v)
{
v += 5;
}
int main()
{
int foo = 3;
Plus5( foo ); // makes sense
Plus5( 6 ); // wtf
}
Does this also mean for STL implementers, they tend to overload functions, one with const and one without const in their arguments ?
E.g
class Test {
public:
void add(Test&);
void add(const Test&);
...
}
Since library users are going to use the class with passing in const and non-const arguments, having two version will ensure that the library class can be used and compile correctly ?