2014-10-14 2 views
3

나는 다음과 같은 코드가 있습니다복사 생성자 "구조체 원자"

    : 나는 몇 가지 질문이

    // c++ header file - atomic 
    template<typename _Tp> 
        struct atomic 
        { 
        private: 
        _Tp _M_i; 
    
        public: 
        atomic() noexcept = default; 
        ~atomic() noexcept = default; 
        atomic(const atomic&) = delete;    <--- Line c 
        atomic& operator=(const atomic&) = delete; 
        atomic& operator=(const atomic&) volatile = delete; 
    
        constexpr atomic(_Tp __i) noexcept : _M_i(__i) { } <--- Line d 
    
        operator _Tp() const noexcept 
        { return load(); } 
    
        operator _Tp() const volatile noexcept 
        { return load(); } 
    
        _Tp 
        operator=(_Tp __i) noexcept 
        { store(__i); return __i; } 
    .... 
    

    :

    enum class State : uint32_t 
    { 
        FREE, 
        IDLE, 
        COAST, 
        MOVE, 
        STOP 
    }; 
    
    std::atomic<State> car1_state = State::IDLE; <--- Line a 
    std::atomic<State> car2_state(State::IDLE); <--- Line b 
    

    다음은 원자 헤더 파일의 미리보기입니다

  • 라인 b이 정상적으로 컴파일됩니다. 내 이해 생성자 라인 d에서 호출됩니다. 권리?
  • 라인 은 컴파일에 실패합니다. 오류 메시지 당 행의 복사 생성자가 호출되므로 "삭제 된 함수 사용"오류 메시지가 표시됩니다.

누군가는 라인 가 C (및 D 라인되지 않음) 라인 를 호출 끝 어떻게 왜/나를 이해하는 데 도움이 바랍니다 수 있습니다.

답변

5

사본 초기화는 동일한 유형의 임시 값에서 공식적으로 변수를 초기화하므로 액세스 가능하고 명시 적이지 않은 사본 또는 이동 생성자가 필요합니다.

Foo a = Foo(x); 

귀하의 유형이 접근 복사 생성자, 따라서 오류가없는 : 그

Foo a = x; 

는 것과 같습니다이다. 반대로 직접 초기화에는 복사 생성자가 필요하지 않습니다.

Foo a(x); 
+0

감사합니다. "Foo a = Foo (x);"라고 말하면 Foo 생성자 (x는 param), Foo 복사 생성자 (temp 객체를 참조). 또한, Foo (x)가 임시 (prvalue)이기 때문에 궁금 해서요, 왜 생성자를 호출하지 않았습니까? 그렇지 않습니까? –

+0

@AhmedA : 사본을 실제로 만들 필요는 없지만 적합한 생성자는 정식으로 액세스 할 수 있어야합니다. 예, 복사 또는 이동 생성자가 좋습니다. –

+0

Foo (x)가 오류 또는 Foo a = 을 발생시키는 이유는 무엇입니까? 후자를 추측하고 있는데 복사 생성자가 호출되는 지점이므로 삭제 된 것으로 표시됩니다. –

2

직접 초기화와 복사 초기화 간의 차이점은 다음과 같습니다. 현실을 일반화하자

A a1 = b; 
A a2(b); 

b의 유형 A 경우, 두 개의 선이 동일합니다. 이들은 모두 A의 복사 생성자를 호출합니다.

그러나 b 유형이 A과 다른 경우 해당 의미도 다릅니다. a2직접 초기화로으로 초기화되며 A의 적절한 생성자를 호출하여 b 유형을 취합니다.

a1

는, 다른 한편으로는, 복사 초기화로 작동에 의해 초기화된다 "인수에서 임시 객체를 초기화 한 후 최종 목적으로 일시적 것을 복사하는 복사 생성자를 사용합니다." 복사 생성자가 삭제되기 때문에, 귀하의 경우에는

A a1(A(b)); 

이 실패하고 더 이동 생성자가 없다 :이 경우에 그래서, 복사 초기화이 동일합니다.

그리고 완전히 두 번째 질문에 대답하기 위해서는 라인 D에 추가 라인 D,하지만 의 대신 선 C를 호출하지 않습니다.