boost::optional 抽象 class 类型

boost::optional abstract class type

我想要一个抽象类型的可选对象。 但是,boost::optional 对抽象类型失败:

#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);
};

结果

error: invalid new-expression of abstract class type ‘A’

仅仅使用指针似乎也不是一个可行的解决方案,因为某些函数需要 return 一个包含可选值的对象作为成员,尽管期望函数的调用者这样做是不合逻辑的成为该成员变量的所有者。

你不能按照你想要的方式去做。

optional 尝试创建类型为 A 的成员(在您的情况下)但失败了。

我想到并使用的唯一解决方案是存储(智能)指针。

Optional 有值语义,所以你不能做你想做的事,就像你不能实例化 A 本身一样:

A anA;

因为您似乎对引用一个可选值感兴趣,而不是owning/containing它:

你可以有一个包含参考的可选:

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

这样你就可以拥有和传递时完全一样的A&但可选

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();
}

版画

666

如果您/确实/希望optional充当该类型的容器,您确实应该使用unique_ptr<A>(它已经可以为空,可转移并拥有资源)。