boost optional 承认继承?

boost optional recognizes inheritance?

class Base {};
class Derived : public Base {};

void func(boost::optional<Base>&) {}

int main () {
  boost::optional<Derived> x;
  func(x);
}

func 会接受两个可选值:base 和 derived 吗?

即使它可以工作(这很可能是我没有检查过的),它也会导致切片。只有 Base 部分会存储在 optional.

可选在内部保留一个缓冲区,其大小需要存储Base。即使 Base 的大小与 Derived 相同(如您的情况),它仍然只会存储 Base.


编辑:

以上答案是针对包含以下代码的原始问题给出的:

int main () {
  boost::optional x(Derived());
  func(x);
}

这样的代码是不正确的,原因有二:

  1. boost::optional 需要模板参数
  2. 即使使用模板参数,它仍然是函数声明。

我忽略了这些问题,并假设是这样的意思:

int main () {
  boost::optional<Base> x = Derived();
  func(x);
}

虽然该代码确实可以编译(至少 Visual Studio 2013 和 Boost 1.60)并导致切片。 运行 下面的程序可以看出:

#include <boost/optional.hpp>
#include <iostream>

class Base
{
public:
    virtual ~Base() { std::cout << "~Base" << std::endl; }
};

class Derived : public Base
{
public:
    virtual ~Derived() { std::cout << "~Derived" << std::endl; }
};

int main()
{
    boost::optional<Base> x = Derived();
}

产生输出

~Derived
~Base
~Base

第二个 ~Base 表明 optional 销毁了 Base 对象而不是 Derived 对象。 (~Derived 和第一个 ~Base 来自临时对象 Derived()。)

不,它不会起作用。 func 接受对 boost::optional<Base> 的左值引用。这意味着它可以接受 boost::optional<Base> 类型的左值,公开且明确派生自 boost::optional<Base> 的类型的左值,或具有 operator boost::optional<Base>&() 的其他类型的左值。 None boost::optional<Derived> 是正确的。 Class 模板在 C++ 类型系统中不协变 - boost::optional<Derived> 不继承自 boost::optional<Base>


如果func按价值来论证,情况就会不同。如果它看起来像:

void func(boost::optional<Base> ) { }

在那种情况下,您可以boost::optional<Derived>调用func。但是那个转换构造函数被标记为 explicit,所以你必须写:

func(boost::optional<Base>{x});

这是明确的好 - 你清楚地标记你正在(可能)切片 x