Operator=()를 사용할 때 copy-ctor를 사용하는 C++ - 정확히 어떻게 작동합니까?

StackOverflow https://stackoverflow.com//questions/23025259

문제

C++에서 연산자=() 할당을 구성으로 변환하는 규칙은 정확히 무엇입니까?와 같은 Foo foo = bar 실제로 bar가 존재하는 경우 인수로 받아들이는 Foo의 생성자를 호출합니다.이것이 어떻게 작동하는지 검색했지만 아무것도 찾을 수 없는 것 같습니다.

아래 할당이 생성자를 가져오려고 하지만 분명히 올바른 생성자를 가져오지 않는 이유를 파악하는 데 문제가 있습니다.HandlePtr( 유형 및 리소스 ).실제 구성 구문을 사용한 구성은 잘 작동하지만 할당 연산자를 사용하면 작동하지 않습니다.

코드(분명히 간결하게 편집됨):

template< typename TYPE >
class HandlePtr {
public:
    HandlePtr( void ) = default;
    HandlePtr( HandlePtr< TYPE >& other ) = default;
    HandlePtr( TYPE& resource ) {} // generally I would make this explicit, but for testing purposes I took it out
    ~HandlePtr( void ) = default;

public:
    HandlePtr<TYPE>& operator=( TYPE& resource ) { return *this; }
    HandlePtr<TYPE>& operator=( HandlePtr<TYPE>& other ) { return *this; }
};

int main ( void ) {
    int x = 5;
    HandlePtr< int > g( x ); // works
    HandlePtr< int > i;i = x; // works
    HandlePtr< int > h = x; // doesn't work

            // also tried this just out of curiosity:
    HandlePtr< int > h = HandlePtr< int >( x ); // also does not work

    return 0;
}

오류:

shit.cpp: In function ‘int main()’:
try.cpp:19:24: error: no matching function for call to ‘HandlePtr<int>::HandlePtr(HandlePtr<int>)’
   HandlePtr< int > h = x; // doesn't work
                        ^
try.cpp:19:24: note: candidates are:
try.cpp:7:3: note: HandlePtr<TYPE>::HandlePtr(TYPE&) [with TYPE = int]
   HandlePtr( TYPE& resource ) {} // generally I would make this explicit, but for testing purposes I took it out
   ^
try.cpp:7:3: note:   no known conversion for argument 1 from ‘HandlePtr<int>’ to ‘int&’
try.cpp:6:3: note: HandlePtr<TYPE>::HandlePtr(HandlePtr<TYPE>&) [with TYPE = int]
   HandlePtr( HandlePtr< TYPE >& other ) = default;
   ^
try.cpp:6:3: note:   no known conversion for argument 1 from ‘HandlePtr<int>’ to ‘HandlePtr<int>&’
try.cpp:5:3: note: HandlePtr<TYPE>::HandlePtr() [with TYPE = int]
   HandlePtr( void ) = default;
   ^
try.cpp:5:3: note:   candidate expects 0 arguments, 1 provided
try.cpp:20:20: error: redeclaration of ‘HandlePtr<int> h’
   HandlePtr< int > h = HandlePtr< int >( x ); // also does not work
                    ^
try.cpp:19:20: error: ‘HandlePtr<int> h’ previously declared here
   HandlePtr< int > h = x; // doesn't work
도움이 되었습니까?

해결책

당신은 그것을 간과하고 있습니다. 선언:

T t = u;

이것은 할당 연산자가 아닙니다. t = u; 선언의 하위 표현식이 아닙니다.여기서 유일한 표현은 다음과 같습니다. u;그리고 표현식을 평가한 결과 u 객체의 초기화 프로그램으로 사용됩니다. t 선언되고 있습니다.

만약에 u 유형이 있음 T, 그 다음에 t 다음에서 복사하여 구성되었습니다. u.

만약에 u 유형이 없습니다 T, 그 다음에 u 먼저 유형으로 변환해야 합니다. T.이는 rvalue 유형의 T.

rvalue를 허용하는 생성자가 없으므로 T t = u;, 그리고 동일한 T t = T(u); 둘 다 실패합니다.하지만, T t(u) rvalue가 생성되지 않았기 때문에 성공합니다.가치 u 생성자에 대한 인수로 사용됩니다. T(U &).

단순화된 코드 예:

struct T
{
    T(int &);
    T(T&);
    T();
    T &operator=(int &);
};

int main()
{
    int x = 5;
    T g(x);   // OK, T(int &)
    T g2(5);   // fail, looks for T(int const &)
    T i;      // OK, T()
    i = x;    // OK, T::operator=(int&)
    T h3 = i; // OK, T(T&)
    T h1 = T(x);    // fail, looks for T(T const &)
    T h2 = x;       // fail, identical to previous line 
}

일반적으로 다음을 사용해야 합니다. const & 복사 생성자 및 할당 연산자의 매개변수로 사용됩니다.그런 다음 rvalue가 const 참조에 바인딩될 수 있으므로 이러한 "실패" 사례는 모두 "OK"가 됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top