Search code examples
c++referencevisual-studio-2017c++14std-pair

Do I Need to use ref With make_pair to Return a Reference?


Given an object like this one:

struct Foo {
    string _mem;
    pair<bool, const string&> Func() { return make_pair(true, _mem); }
};

Am I actually returning a reference to _mem or not? My understanding was that in make_pair would forward my type allowing the return I'm using to capture it as a reference to the object's _mem.

This behavior seems consistent with what I'm seeing in gcc 8: http://ideone.com/adz17e But when I try to run this on it seg-faults. If I change to return make_pair(true, ref(_mem)) it works, but I didn't think that I needed to. Which one of these behaviors is correct?


Solution

  • Am I actually returning a reference to _mem or not?

    No, you are not. make_pair(true, _mem) is a std::pair<bool, std::string> that is a copy of that your member. It's then converted to a std::pair<bool, std::string const&> in the return type which means you're returning a reference to a temporary which is immediately destroyed. Unconditional dangling.

    Recall that C++ is a value semantics language. Nothing is a reference by default, you have to be explicit about this.

    You have two ways of doing this. You can either mark that you want a reference:

    return std::make_pair(true, std::ref(_mem));
    

    make_pair will unwrap std::reference_wrappers, so this expression is a std::pair<bool, std::string&>.

    Or, you can just be explicit:

    return std::pair<bool, std::string const&>(true, _mem);
    

    Which you can write shorter as:

    return {true, _mem};