I was refreshing my memory on the various types of casting available and came across the following on cppreference.com (http://en.cppreference.com/w/cpp/language/dynamic_cast):
1) If the type of expression is the exactly new_type or a less cv-qualified version of new_type, the result is expression.
Referring to the structure
dynamic_cast < new_type > ( expression )
I interpreted that to mean that, for example, attempting a dynamic_cast of a non-const reference to a const reference of the same type would actually yield the non-const reference and therefore allow me to call its non-const members, which is the opposite of what I'd expect. I wrote the following noddy piece of code to check that out:
#include<iostream>
class Base
{
int value;
public:
Base():value(0){};
virtual void ShowVal() const
{
printf("Value is %d\n", value);
}
virtual void SetVal(int val)
{
value = val;
}
};
int main ()
{
Base b;
Base& rB = b;
b.ShowVal();
(dynamic_cast<const Base&>(rB)).SetVal(2); //fails where (dynamic_cast<Base&>(rB)).SetVal(2); is obviously fine.
b.ShowVal();
}
As I'd have expected anyway, this doesn't compile and I get the error
blah.cpp:28:3: error: member function 'SetVal' not viable: 'this' argument has type 'const Base', but function is not marked const
(dynamic_cast<const Base&>(rB)).SetVal(2);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I suppose the question I'm meandering towards is: Have I misunderstood the rule above? And if so, what is it actually saying and is there a similarly basic example that demonstrates it?
Thanks. (In the meantime I'm going to read it again, and if I realise I've misread it then I'll quickly delete this question and commence facepalming...)
It's not so obvious from the way that's written, but the conversion still takes place. It just means that the object you get from the conversion (the pointer or reference) is the same as the one denoted by expression
. The cast expression is of const
type though because that's what you converted it to.
Here's what it looks like in the C++11 standard:
If the type of
v
is the same asT
, or it is the same asT
except that the class object type inT
is more cv-qualified than the class object type inv
, the result isv
(converted if necessary).
Note the "converted if necessary".
You might wonder why it even bothers saying that the result is expression
? For most dynamic_cast
s, the result is not expression
. Consider casting from a pointer to base class to a pointer to derived class. You don't get the same pointer out of it. Instead, you get a pointer to the derived subobject.