Reputation: 447
Chapter 4.11.3 of the book C++ Primer says the following:
A named cast has the following form:
cast-name<type>(expression);
wheretype
is the target type of the conversion, andexpression
is the value to be cast. If type is a reference, then the result is an lvalue.
Can anyone give an example of this? Is conversion to a reference even possible?
Upvotes: 3
Views: 2885
Reputation: 990
Is conversion to a reference even possible?
Yes, depending on the object you begin with.
Most simple example is one lvalue reference converted to another. This can even be an added cv-qualifier (or removed, with const_cast
), such as:
int const & foo(int & i) {
return static_cast<int const &>(i);
}
the derived-to-base casts and base-to-derived (dynamic) casts mentioned in the other answers are other such examples.
A more interesting example is the std::reference_wrapper
, which is an object you can receive as an rvalue, and cast it to an lvalue reference of the contained type:
int & foo(std::reference_wrapper<int> i) {
return static_cast<int &>(i);
}
Note that the cast above happens implicitly (I could've used return i
), but in some contexts (e.g. capturing variables with auto
type) you might want to write the cast explicitly.
What is meant in C++ Primer is simply that the behavior of casts in these examples, and others, is basically what you would expect - the result of a cast to a reference type is an lvalue.
Upvotes: 4
Reputation: 485
Example when type
is not a reference: If i
is a variable of type int
, then static_cast<long int>(i)
returns a non-lvalue of type long int
.
Example when type
is a reference: static_cast<Base&>(objectOfDerivedType)
returns an lvalue of type reference-to-Base.
Upvotes: 0
Reputation: 16726
Here is a short example with a class hierarchy. In main you find code that constructs a Derived
object on the heap and stores the pointer to it in p
. If you want to work with pointers, you can just dynamic_cast<Derived*>
that pointer. But sometimes like in function work
you have a reference to the base class. If inside the function you know at some place that the object b
is of type Derived
(maybe you checked an enum member giving you the type or based on some other information you know that it must be some special type), then can directly cast from reference Base&
to reference Derived&
. In that special case of dynamic_cast
it also makes a difference because casting a pointer will return nullptr
if the cast is not possible, but casting a reference will throw an exception if the cast is not possible.
#include <memory>
struct Base {
virtual ~Base() = default;
};
struct Derived : Base {
void f() const noexcept {}
};
void work(const Base& b) noexcept
{
// Check what to do, then assume it must be a Derived, then work on it:
dynamic_cast<const Derived&>(b).f();
}
int main() {
std::unique_ptr<Base> p{ std::make_unique<Derived>() };
dynamic_cast<Derived*>(p.get())->f();
work(*p);
return 0;
}
Upvotes: 0