简体   繁体   中英

Does std::make_tuple() not work with objects of type std::optional?

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>;
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM