为 std::optional 个对象中的 std::array 个对象赋值

Assigning values to std::array of std::optional objects

我正在尝试填充 std::array 个 std::optional 个对象,如下所示。

class MyClass
{
   private:
    int distance;
    MyClass(int x, int y);

   friend class MasterClass;
};

MyClass::MyClass(int x, int y)
{
  distance = x+y;
}

class MasterClass
{
  public:
  MasterClass(std::array<std::optional<int>,5> xs, std::array<std::optional<int>,5> ys);
  
  private:
  std::array<std::optional<MyClass>, 5> myclassarray{};

};

MasterClass::MasterClass(std::array<std::optional<int>,5> xs, std::array<std::optional<int>,5> ys)
 {
     for(int i=0; i<5;i++)
     {
         myclassarray[i].emplace(new  MyClass(*xs[i], *ys[i])); //---(1)
     }

 }

从上面用 (1) 注释的行,我得到以下错误,

error: no matching function for call to std::optional<MyClass>::emplace(MyClass&)

我也尝试用

替换同一行
 myclassarray[i] = new  MyClass(*xs[i], *ys[i]) ; //---(2)

这会给我

error: no match for ‘operator=’ (operand types are ‘std::array<std::optional<MyClass>,5>::value_type’ {aka ‘std::optional<MyClass>’} and ‘MyClass*’)

如何解决这个问题?

看起来您可能来自 Java,或 C#。在 C++ 中赋值时,很少会使用 new。问题是,你基本上是这样做的:

std::optional<MyClass> o = new MyClass();

o是类型,std::optional<MyClass>new My Class()MyClass *类型。从here可以看出,没有将指向对象的指针转换为对象的可选的操作。让我们回到基础,我们想要做的是:

std::optional<int> o; // defaults to std::nullopt
o = value; // We set it with some value.

实际上这就是它的全部内容。所以让我们扩展到一个数组:

std::array<std::optional<int>, 5> a; // An array with 5 optional, all are std::nullopt
a[2] = value; // Set the optional at position 2 to a value.

这很容易扩展到您的示例:

for(int i=0; i<5;i++) {
     myclassarray[i] = MyClass(*xs[i], *ys[i]));
}

请注意这一点:

*xs[i], *ys[i]

因为来自 here:

The behavior is undefined if *this does not contain a value.

如果是这样的话,你会很伤心的。