2

copy/move elision이 생성자 복사/이동 작업자와 복사/이동 생성자를 명시 적으로 delete d 적용하거나 적용 할 수 있는지 알고 싶습니다. 명시 적으로 삭제 된 복사/이동 생성자에 대한 복사/이동

  1. 가 명시 적으로 delete D 복사의 ctor이 나 ctor에

    를 생략받을 이동할 수 있습니다 여기에 세부 사항은 무엇입니까? delete 사본 카피 및/또는 delete 카피를 건너 뛰어도 성공할 수있는 다른 동일한 유형의 개체 또는 임시 개체로 개체를 만들려고 시도 했습니까? 컴파일러는 '아무튼 Error: function “Foo::Foo(Foo &&)” ... cannot be referenced – it is a deleted function :

    #include <iostream> 
    
    struct Foo { 
        Foo() { std::cout << "default ctor\n"; } 
        Foo(Foo const&) = delete; 
        Foo(Foo&&) = delete; 
    }; 
    
    int main() { 
             // ----Output------ 
        Foo{ Foo() };  // "default ctor" 
        Foo f;    // "default ctor" 
        Foo{ std::move(f) }; // error C2280: 'Foo::Foo(Foo &&)' : attempting to reference a deleted function 
        Foo{ f };   // error C2280: 'Foo::Foo(const Foo &)' : attempting to reference a deleted function 
    } 
    

    에도 인텔리 불구하고 약 Foo{ Foo() }; 불평 :

    여기 (복사/이동 생략을 해제 할 수있는 옵션이 있다면있는 잘 모르겠어요) VC12에서 발생하는 상황 거기에 불평이 없기 때문에 그 줄은 여전히 ​​컴파일됩니다.

  2. Foo{ Foo() };은 작동하지만 Foo{ std::move(f) };이 아닌가? 한 번의 호출로 이동 영역이 사라지면 다른 영역이 없어야합니까?

  3. Foo{ Foo() };은 작동하지만 Foo{ f };이 아닌가? 이 선택성은 임의적으로 보입니다. const 참조에 대한 rvalue 참조의 이와 같은 임의적 선호는 non-ctor 메소드에는 적용되지 않는 것처럼 보입니다. 여기서 통화에서, 만약 그렇지 않은 delete D 과부하보다 높은 과부하 해상도 우선했을 delete D 과부하 상기 delete D 한 블록 컴파일러 에러 발생 비 delete D 하나 :

    struct Bar { 
        void g(int const&) {} 
        void g(int&&) = delete; 
    }; 
    
    //… 
    Bar b; 
    b.g(2); //error C2280: 'void Bar::g(int &&)' : attempting to reference a deleted function 
    //^Would have compiled had function `g(int&&)` been commented out. 
    

    해당 논리에 따르면 delete d Foo(Foo&&)은 인수가 임시가 아닌 경우 Foo(Foo const&)에 대한 호출을 차단해서는 안됩니다. Foo(Foo&&)은이 경우 Foo(Foo const&)보다 낮은 과부하 해결 우선 순위를 갖습니다.

  4. copy elision이 비활성화되어 (플래그 -fno-elide-constructors을 통해) ged가 활성화 된 상태에서 g ++ 4.8에서 동일한 Foo 예제를 시도했습니다. 두 g의 ++ 시험은 준 : 컴파일러가 올바른지 Foo{ f };

    에 대한 Foo{ Foo() };에 대한

    error: use of deleted function 'Foo::Foo(Foo&&)'

    error: use of deleted function 'Foo::Foo(const Foo&)'?

답변

3

Ms VC++에는 매우 오래된 잘 알려진 버그가 있습니다. 구현이 단락 번호에서 설명/복사를 생략 클래스 오브젝트의 구성을 이동시킬 수있는 C++ 표준

[ Note: This two-stage overload resolution must be performed regardless of whether copy elision will occur. It determines the constructor to be called if elision is not performed, and the selected constructor must be accessible even if the call is elided. —end note ]

+0

기준에서 섹션 (31) C++ Standard.It 12.8 복사 및 이동 클래스 오브젝트는 충분히 길다 절. –