Search code examples
c++boostboost-optional

boost optional recognizes inheritance?


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?


Solution

  • 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.