This is the source code:
using namespace std;
class obj {
public:
obj() = default;
obj(int i) : i_{i} {}
int I() const {return i_;}
int const & rI() const {return i_;}
void I(int i) {i_ = i;}
void show() const {cout << "addr = " << this << ", i_ = " << I() << endl;}
private:
int i_{0};
};
struct {
optional<obj> o_0 {nullopt};
optional<obj> o_1 {nullopt};
optional<obj> o_2 {nullopt};
void set_o0(obj o_) {o_0 = o_;}
void set_o1(obj o_) {o_1 = o_;}
void set_o2(obj o_) {o_2 = o_;}
tuple<optional<obj>, optional<obj>, optional<obj>> get_obj() {
return make_tuple<o_0, o_1, o_2>;
}
} opts_;
Trying to return a std::tuple composed of type std::optional<> does not seem to work. The following error message is reported which is not particularly that helpful. Can anyone help?
<source>: In member function 'std::tuple<std::optional<obj>, std::optional<obj>, std::optional<obj> ><unnamed struct>::get_obj()':
<source>:40:27: error: use of 'this' in a constant expression
40 | return make_tuple<o_0, o_1, o_2>;
| ^~~
<source>:40:32: error: use of 'this' in a constant expression
40 | return make_tuple<o_0, o_1, o_2>;
| ^~~
<source>:40:37: error: use of 'this' in a constant expression
40 | return make_tuple<o_0, o_1, o_2>;
| ^~~
<source>:40:16: error: cannot resolve overloaded function 'make_tuple' based on conversion to type 'std::tuple<std::optional<obj>, std::optional<obj>, std::optional<obj> >'
40 | return make_tuple<o_0, o_1, o_2>;
| ^~~~~~~~~~~~~~~~~~~~~~~~~
CodePudding user response:
std::make_optional
is a function template. Its purpose is to deduce the tuples types from the parameters passed to it.
Rather than explicitly listing the template arguments you should let them be deduced from the parameter. And you need to actually call the function:
auto get_obj() {
return std::make_tuple(o_0, o_1, o_2);
}
Note that you can use auto
for the return type. If you do not use the auto
return type you do not need make_tuple
(because as I said, its purpose is to deduce the tuples types, but when the type is already known this isnt required):
std::tuple<std::optional<obj>, std::optional<obj>, std::optional<obj>> get_obj() {
return {o_0, o_1, o_2};
}