class Base {};
class Derived : public Base {};
void func(boost::optional<Base>&) {}
int main () {
boost::optional<Derived> x;
func(x);
}
will func accept both optionals: base and derived?
No, it won't work. func
takes an lvalue reference to boost::optional<Base>
. That means it can accept an lvalue of type boost::optional<Base>
, an lvalue of a type that derives publicly and unambiguously from boost::optional<Base>
, or some other type that has an operator boost::optional<Base>&()
. None of those is true of boost::optional<Derived>
. Class templates are not coviarant in the C++ type system - boost::optional<Derived>
does not inherit from boost::optional<Base>
.
It would be a different story if func
took its argument by value. If it looked like:
void func(boost::optional<Base> ) { }
In that case, you could call func
with a boost::optional<Derived>
. But that converting constructor is marked explicit
, so you would have to write:
func(boost::optional<Base>{x});
It's good that this is explicit - you are marking clear that you are (potentially) slicing x
.