왜
std::tie(a,b) = {b, a};
컴파일하지 않는 이유는 무엇입니까?
{}
은 할당의 오른쪽 부분에만 operator=
의 논리적이지 않은 생성자를 호출 할 수 있습니다. 사용할
operator=
과부하은 :
tuple& operator=(const tuple& other);
tuple& operator=(tuple&& other);
template< class... UTypes >
tuple& operator=(const tuple<UTypes...>& other);
template< class... UTypes >
tuple& operator=(tuple<UTypes...>&& other);
template< class U1, class U2 >
tuple& operator=(const pair<U1,U2>& p);
template< class U1, class U2 >
tuple& operator=(pair<U1,U2>&& p);
template
연산자 과부하가 {}
에서 그들의 타입을 추론 할 수 없다 (참고 : 이는 C++ 17 변경할 수있다), 이탈 :
tuple& operator=(const tuple& other);
tuple& operator=(tuple&& other);
곳 이 경우 tuple
은 std::tuple<int&, int&>
입니다.
tuple<Ts...>
에 대한 tuple 생성자는 요소 방식으로 완벽한 전달은 explicit (해당 목록에서 # 3)입니다. {}
은 명시 적 생성자를 호출하지 않습니다.
조건부 비표시 생성자는 Ts const&...
을 사용합니다. Ts
이 복사 불가능하고 int&
이 복사 불가능한 경우 존재하지 않습니다.
따라서 {int&, int&}
에서 구성 할 실제 유형이없고 과부하 해결에 실패합니다.
표준이이 문제를 해결하지 않는 이유는 무엇입니까? 글쎄, 우리 스스로 할 수있어!
이 문제를 해결하려면유형이 모두 참조 인 경우에만 tuple
에 특수한 (Ts...)
명시 적 생성자를 추가해야합니다.
우리가 장난감 튜플 작성하는 경우 :
struct toy {
std::tuple<int&, int&> data;
toy(int& a, int& b):data(a,b) {} // note, non-explicit!
};
toy toy_tie(int& a, int& b) { return {a,b}; }
및 사용을, 당신이 알 수
std::tie(a, b) = {b, a};
컴파일 및 실행합니다. a%b
이 int&
에 바인딩 할 수 없기 때문에
그러나
,
std::tie(a, b) = { b, a % b };
은하지 않습니다.
우리는 다음과 toy
보강 할 수 있습니다 : (. + 특별 회원 기능을 디폴트 예상대로 template<class...>
, 그것은 특별한 멤버 함수보다 우선 순위가 보장)
template<class...>
toy& operator=(std::tuple<int, int> o) {
data = o;
return *this;
}
합니다.
할당자를 {int,int}
에서 할당 할 수 있습니다. 우리는 그것을 실행하고 ... 잘못된 결과를 얻습니다. 5,20
의 gcd는 20
입니다. 무엇이 잘못 되었습니까? 참조에 바인드 모두 a
및 b
와
toy_tie(a, b) = std::tie(b, a);
안전 코드가 아닙니다, 그것은
toy_tie(a, b) = { b, a };
가하는 일입니다.
간단히 말해서,이 권리를하는 것은 까다 롭습니다. 이 경우 안전을 위해 할당하기 전에 사본을 오른쪽으로 가져 가야합니다. 언제 사본을 가져야하는지 알지 못하는 경우 또한 까다 롭습니다.
이 작업을 수행하면 암시 적으로 오류가 발생합니다. 어떤 의미에서는 우연히 작동하지 않지만 가능하다면 해결하는 것은 나쁜 생각처럼 보입니다.
live example.
위대한 설명 .. 나는 Python의 다중 할당 (예 : a, b = b, a % b)에 영향을 받았지만이 안전하게 당신은 매번 (파이썬 않습니다) –