0

I cant figere out if RVO (return value optimalization) is guaranteed to happen in case of std::pair assigment with [] syntax. Exapmple:

std::pair<vector<double>,vector<double> > my_funct() {
    std::pair<vector<double>, vector<double> > _result;
    auto& [x, y] = _result;

    // do some calculation and fill up x, y

    return _result;
}


int main() {

    // auto result = my_funct(); // RVO is guranteed in this case.

    auto [x, y] = my_funct(); // Does Return value optimalization happens (guranteed by c++17)?

    return 0;
}
  • 1
    RVO is not guaranteed in your case, because there is no RVO. It is NRVO (you are returning a named object), which is never guaranteed. – Daniel Langr Apr 27 '21 at 11:29
  • That's a **named** return value, so it's not guaranteed in any case (yet; there is a proposal about guaranteed copy elision for NRVO ongoing). But recall that the structured binding declaration declares an unnamed object of the compound type, so normal RVO/NRVO does or does not apply as if you directly captured said compound object. – underscore_d Apr 27 '21 at 11:29

1 Answers1

1

I cant figere out if RVO (return value optimalization) is guaranteed to happen in case

return _result;

You're returning an lvalue. RVO is not guaranteed to happen.


RVO would work with auto [x, y] = my_funct() in the case my_funct were eligible to guaranteed RVO.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Would it work with `return std::pair, vector > {x, y};` with `vector x, y;` at the start of the function? Something like https://godbolt.org/z/7ezx9Ye1W – mch Apr 27 '21 at 11:40
  • @mch The pair would be guaranteed to be RVO'ed. But the vector members of the pair may be copied when constructing the RVO'd pair. – eerorika Apr 27 '21 at 11:47
  • `x`, `y` have to be copied. – Jarod42 Apr 27 '21 at 11:51
  • @eerorika Will `return std::pair, vector>{ std::move(x), std::move(y) };` make those vectors in the pair be move-constructed? It seems to work: https://godbolt.org/z/b9hK4s481. – Daniel Langr Apr 27 '21 at 11:55
  • 1
    @DanielLangr Yes. You could also just do `return {vector(args), vector(args)};` for maximum copy/move elision – eerorika Apr 27 '21 at 11:58
  • @DanielLangr Hmm, never mind the second sentence of last comment. For some reason, the compiler really doesn't like that, at least with your demo code. Moving from lvalue appears to be strangely better than a prvalue in this case. – eerorika Apr 27 '21 at 12:07