I am trying to fill a std::array of std::optional objects as below.
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)
}
}
From the line commented with (1) above, I get the following error,
error: no matching function for call to std::optional<MyClass>::emplace(MyClass&)
I also tried replacing the same line with
myclassarray[i] = new MyClass(*xs[i], *ys[i]) ; //---(2)
This will give me
error: no match for ‘operator=’ (operand types are ‘std::array<std::optional<MyClass>,5>::value_type’ {aka ‘std::optional<MyClass>’} and ‘MyClass*’)
How do I solve this issue?
Looks like maybe you are coming from Java, or C#. When you assign a value in c++, it is rare that you will use new
. The issue is, that you are basically doing this:
std::optional<MyClass> o = new MyClass();
o is of type, std::optional<MyClass>
and new My Class()
is of type MyClass *
. You can see from here that there is no operation that converts a pointer to an object to an optional of an object. Lets take this back to basics, what we want to do is something like:
std::optional<int> o; // defaults to std::nullopt
o = value; // We set it with some value.
And actually this is all there is to it. So lets expand to an array:
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.
And this extends easily to your example:
for(int i=0; i<5;i++) {
myclassarray[i] = MyClass(*xs[i], *ys[i]));
}
Just be careful with this bit:
*xs[i], *ys[i]
because from here:
The behavior is undefined if *this does not contain a value.
Which will cause you much grief if this is the case.