Can I rely on named return value optimization for complex return types?

Consider something like the following:

typedef std::unordered_multiset<int> Set;
typedef std::set<Set> SetOfSets;

SetOfSets somethingRecursive(SomeType somethingToAnalyze) {
    Set s;
    // ...
    // check base cases, reduce somethingToAnalyze, fill in s
    // ...
    SetOfSets ss = somethingRecursive(somethingToAnalyze);
    ss.insert(s);
    return ss;
}

This approach is fairly standard for tasks such as creating subsets, permutations, etc. However, I tried to chart out what exactly Return Value Optimization should be optimized here, given the rather complex internal data structure of the type ( std::unordered_multisetis a hash table and std::setis usually a binary search tree), and I can only hope that the compilers are smarter than me .

So, speaking performance and (in case that matters) C++14, can I return SetOfSetshere or can I just pass it by reference as an out parameter?

+4
3

++ 17 , . , , , (, GCC -O0, -fno-elide-constructors, ).

std::set , NRVO .

, ++ 17 NRVO . RVO .


, IMO, ++ 17 RVO, , prnoue, /. , . , , copy/move constructor prvalue ++ 17:

#include <atomic>

std::atomic<int> f() {
  return std::atomic<int>{0};
}

int main() {
  std::atomic<int> i = f();
}

++ 14 .

+4

, ( , ) ++ 14, SetOfSets out?

, , . . elision 1 , .

[class.copy.elision]/1

, / , / / .

, , - , .


1) constexpr

0

. , , .

AFAIK copy_elision.

: " , , - , copy/move ".

NRVO ( ). RVO, , , ++ 17. .

, , "" . , , : " , - , ( cv- )". , , .

, , , , , .


The only reference is an explicit indication that optimization is allowed for types with side effects when building and destroying. But this serves as an exclusive clause. For types without side effects, this is already possible by default.

0
source

Source: https://habr.com/ru/post/1692875/


All Articles