>

다음과 같은 것을 고려하십시오 :

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

이 접근법은 부분 집합, 순열 등의 문제에 대해 상당히 표준 적입니다. 그러나 상당히 복잡한 내부 데이터 구조 ( std::unordered_multiset )를 감안할 때 여기에서 정확히 Return Value Optimization이 최적화해야하는 것에 대한 다이어그램을 만들려고했습니다.  해시 테이블이며 std::set  '보통 이진 검색 트리'입니다. 물론 컴파일러가 나보다 똑똑해지기를 바랍니다.

따라서 말하기 성능과 (필요한 경우) C++14 SetOfSets 를 반환 할 수 있습니까  여기 또는 그냥 매개 변수로 참조로 전달해야합니까?

  • 답변 # 1

    C ++ 17 이전에는 선택 사항이므로 복사 제거에 의존 할 수 없습니다. 그러나 모든 주류 컴파일러는 적용 할 가능성이 높습니다 (예 : GCC는 -O0 에서도 적용합니다)  최적화 플래그, -fno-elide-constructors 에 의해 명시 적으로 복사 제거를 비활성화해야합니다  원한다면)

    그러나 pyzwyz  이동 의미론을 지원하므로 NRVO가 없어도 코드가 좋습니다.

    C ++ 17에서는 NRVO도 선택 사항입니다.RVO는 필수입니다.

    <시간>

    기술적으로 올바른 IMO 인 C ++ 17에는 RVO가 없습니다. prvalue가 반환 될 때 임시/이동할 재료가 없기 때문입니다. 규칙은 약간 다르지만 그 효과는 거의 같습니다. C ++ 17에서 복사/이동 생성자가 prvalue를 값으로 반환 할 필요가 없기 때문에 더욱 강력합니다.

    std::set
    
    

    C ++ 14에서이 코드는 컴파일되지 않습니다.

  • 답변 # 2

    실제로는 그렇지 않습니다. 보장되는 것은 아니지만 일반적으로 일반적이므로 필요한 신뢰 수준에 따라 다릅니다.

    AFAIK이 설명은 최신이며 주제 copy_elision을 다룹니다.

    핵심 문장은 다음과 같습니다. "다음과 같은 상황에서컴파일러는 허용되지만 필수는 아님은 복사/이동하더라도 클래스 객체의 복사 및 이동 구성을 생략합니다. 생성자와 소멸자는 관찰 가능한 부작용이 있습니다."

    그런 다음 NRVO에 대한 설명이 있습니다. 그리고 다음 글 머리 기호에는익명 임시 RVO에 대한 설명과이 글이 c ++ 17 이후 필수 인 글 머리 기호가 있습니다. 그렇지 않으면 아무것도 보장되지 않습니다.

    복잡한"이 무엇이든, 복잡한 유형이인지는 중요하지 않습니다. 이러한 최적화는 변수의 상태에 따라 시작됩니다. "어떤 참조에도 묶이지 않은 이름없는 임시는 복사되거나 같은 유형의 객체로 이동되거나 (최상위 cv-qualification 무시)". 이 중 어느 것도 변수유형의 내부 작업과 관련이 없으며 변수가 사용되는 컨텍스트와 관련이 있습니다.

    할 수있는 일은 최소한의 예를 만들어 컴파일러와 분석 어셈블리를 통해 최적화가 시작되었는지 확인하거나 최적화 보고서를 생성하고 자신을 보는 것입니다.

    <시간>

    유일한 참조는 구성 및 파괴에 부작용이있는 유형에 대해 최적화가 허용된다는 명시 적 진술입니다. 그러나 이것은 탁월한 활성화 조항으로 사용됩니다. 부작용이없는 유형의 경우 기본적으로 이미 가능합니다.

  • 답변 # 3

    #include <atomic> std::atomic<int> f() { return std::atomic<int>{0}; } int main() { std::atomic<int> i = f(); }

    괜찮은 컴파일러를 사용하면 복사 제거가 발생하므로 값으로 안전하게 반환 할 수 있습니다. 그러나. 그러나 복사 제거는 보장되지 않으며1올바른 최적화 플래그가 제공되는 경우에만 컴파일러가이를 수행 할 수 있습니다.

    와이즈 비즈 와이즈 비즈      

    특정 기준이 충족되면 생성자가 복사/이동 작업 및/또는 소멸자를 위해 선택된 생성자 인 경우에도 클래스 객체의 복사/이동 구성을 생략 할 수있는허용됩니다. 개체에 부작용이 있습니다.

    이것은 프로그램이 수행되지 않은 경우 프로그램이 여전히 합리적 일 경우에만 복사 제거에 의존해야 함을 의미합니다.

    <시간>

    So, talking performance and (in case it matters) C++14, can I return a SetOfSets here or should I just pass it by reference as an out parameter?

    를 제외한

    1)  사물

  • 이전 c++ - 어셈블리에 SFINAE?
  • 다음 XSLT를 사용하여 XML 행에서 /로 특정 요소 무시 및 추가