I would like to have an optional object of an abstract type. However, boost::optional fails for abstract types:
#include <boost/optional.hpp>
class A {
virtual int getInt() = 0;
};
class B : public A {
int getInt() { return 666; };
};
int main() {
boost::optional<A> maybeAnA;
boost::optional<A> another(maybeAnA);
};
results in
error: invalid new-expression of abstract class type ‘A’
Just using a pointer doesn't seem a viable solution either, since some function needs to return an object containing the optional value as member, though it is not logical to expect the caller of the function to be the owner of that member variable.
Optional has value semantics, so you cannot do what you want for the same reason that you cannot instantiate A
itself:
A anA;
Because you seem to be interested in referring to an optional value, instead of owning/containing it:
You can have an optional containing a reference:
This library allows the template parameter
T
to be of reference type:T&
, and to some extent,T const&
.However, since references are not real objects some restrictions apply and some operations are not available in this case:
- Converting constructors
- Converting assignment
- InPlace construction
- InPlace assignment
- Value-access via pointer
This way you can have exactly the same as when passing A&
, but optional
Live On Coliru
#include <boost/optional.hpp>
struct A {
virtual int getInt() = 0;
};
struct B : A {
int getInt() { return 666; }
};
#include <iostream>
int main() {
boost::optional<A&> maybeAnA;
B b;
maybeAnA = b; // non owning, just the reference
boost::optional<A&> another(maybeAnA);
std::cout << another->getInt();
}
Prints
666
If you /do/ want optional
to act as a container of the type, you should indeed use unique_ptr<A>
(it's already nullable, transferrable and owns the resource).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With