Reputation: 1343
Consider the following code snippet:
class MyClass {
int x;
public:
MyClass(int val) : x(val) {}
const int& get() const {return x;}
};
void print (const MyClass& arg) {
cout << arg.get() << '\n';
}
int main() {
MyClass foo (10);
print(foo);
return 0;
}
Whether I add a const
modifier before the instatiatation of MyClass or not, the program successfully compiles (without any warning) and prints 10
. Why can print
accept a non-const
argument? Or, in other words, what is the function of the const
modifier in the function parameter? Why can the formal and actual parameters of a function have different types (or modifiers)?
I have tried both GCC (4.8.2) and Clang (3.4) with -Wall -std=c++11
on Ubuntu 14.04, and the results were the same (no errors/warnings). I have also searched "c++ const object function" but didn't get anything that looked promising.
Upvotes: 1
Views: 2126
Reputation: 385104
This is completely sane and normal. The object is treated as const
within your function; it does not matter that it was not originally created to be immutable.
Of course, the opposite is not true!
void foo(T& rarr);
int main()
{
const T lolwut;
foo(lolwut); // oops
}
Upvotes: 2
Reputation: 6145
All that const
does in this case is to prevent modification of parameter variable (and in the case of classes, prevent the calling of functions that are not labelled as const
). MyClass
may be trivially cast to const MyClass
because there should be nothing that you can do to a const MyClass
that you can't do to a non-const
one. The reverse is not true, of course.
(I say "should" above, because it is of course possible to completely subvert const
semantics under C++ if you wanted to, so the presence of const
in a function prototype is really only a hopeful hint rather than a cast-iron compiler-enforced guarantee. But no sensible programmer should be breaking things like that!)
Upvotes: 0
Reputation: 137780
const
forbids the body of the function from modifying the parameter variable. Both ways compile because you didn't attempt to modify it.
You can overload const
and non-const
reference parameters, and the const
overload will only be chosen if the argument is really const
(or a type conversion results in a temporary being passed). (For non-reference parameters, const
seldom makes sense and such overloads may not even be defined.)
Upvotes: 0