unique_ptr <0 또는 연산자보다 적은 것은 무엇입니까?


9

내가 작성하지 않은 코드를 다루고 있습니다. 나는이 진술을 가지고있다 :

// p is type of std::unique_ptr<uint8_t[]>
if (p < 0) { /* throw an exception */ }

p < 0이 맥락에서 무엇을 의미합니까?
문서 페이지 , 내 경우와 믿는 16) y < nullptr0입니다 nullptr.

그러나 무엇을 하는가?


1
x64에서 커널 범위의 정식 포인터가 상위 비트 세트를 가지고 있다는 사실을 기반으로 포인터가 커널 공간에 속하는지 확인하는 (멍청한 하드 코딩 된) 방법 일 수 있습니다. .
Michael Chourdakis

1
WINAPI p==-1에서 유효하지 않은 핸들입니다. 2^64엄청나게 큰 숫자 이므로 모든 현명한 p것은 항상 긍정적입니다. 따라서 p<0잘못된 WINAPI 핸들을 확인합니다. 이것은 좋은 코드가 아닙니다.
ALX23z

@OP :이 코드가 어떤 컨텍스트에서 사용되는지 조금 설명해 주시겠습니까? Linux 또는 Windows에서 사용됩니까? 포인터 값이 일부 WINAPI 코드와 관련이 있습니까? 나는 당신이 그것을 분명히하면 위의 의견이 좋은 대답 일 수 있다고 생각합니다.
호두

@ ALX23z 그러나 WINAPI 핸들은 유형 uint8_t*(또는 배열 uint8_t) 이어야 합니까? 나는 그들이 void*아닌 것 같아요 ?
호두

@walnut 그들은 void*매크로 HANDLE_PTR 또는 기본적으로 long*iirc 가 아닙니다 .
ALX23z

답변:


2

unique_ptr <0 또는 연산자보다 적은 것은 무엇입니까?

cppreference의 오버로드 (11)와 일치합니다 operator<(const unique_ptr&, nullptr_t);. 0은로 암시 적으로 변환됩니다 std::nullptr_t. 설명서에 따라 결과는 std::less<unique_ptr<T,D>::pointer>()(x.get(), nullptr)입니다.

결과는 구현이 정의되었지만 대부분의 시스템에서 무조건 거짓입니다. 아마도 null에 이진 표현이 0이 아닌 이국적인 시스템에서는 결과가 사실 일 수 있습니다.

나는 내 사건이 16이라고 믿는다.)

(16)은 다른 방법과 같습니다 0 > unique_ptr. 결과는 같습니다.


그러나 컴파일러 가 0고려 nullptr합니까? 그가 궁금한 것 같아요. 적어도 나에게는 이해가되지 않습니다.
alteredinstance

@alteredinstance 0은 "고려"되지 않습니다 nullptr(또는 고려한 의미에 따라 다름). 0은로 암시 적으로 변환됩니다 std::nullptr_t.
eerorika

그것이 내가 가정 한 것입니다. 의 암시 적 변환에 어떤 문서가 있는지 궁금하네요 0에가 nullptr난 단지 부울 비교와 호환이를 본 적이 있기 때문에. 그것들은 비교할 만하지 만 나는 그들이 전환 할 수 없다는 인상을 받았습니다.
alteredinstance

@alteredinstance 다른 방법으로 변환이 발생하지 않습니다. int x = nullptr형식이 잘못되었습니다.
eerorika

2
@alteredinstance std::nullptr_t는 null 포인터 상수로 사용할 수 있도록 설계되었습니다. 뿐만 아니라 nullptr. 0 (예 : 0L)은 널 포인터 상수이므로을 작성하는 데 사용될 수 있습니다 std::nullptr_t.
eerorika

2

operator <코드베이스 어딘가에 과부하가 걸리지 않았는지 확인하십시오 . 그 유일한 방법은 방법이 될 것으로 보인다 (p < 0)될 수있다 true.

예:

bool operator< (const std::unique_ptr<uint8_t[]>&, int) { return true; }

int main() {
    std::unique_ptr<uint8_t[]> p;
    std::cout << (p < 0) << std::endl;
}

인쇄물:

1

라이브 데모

그렇지 않으면 다른 사람들이 말했듯이 0암시 적으로로 변환하여 호출 할 과부하를 std::nullptr_t선택합니다 ( 포인터 값 이있는 Windows에서도 ).bool operator<(const unique_ptr<T, D>& x, nullptr_t)std::less(p, 0)false-1


반드시 반환 할 필요 는 없습니다 false. 구현 정의되었거나 지정되지 않은 것입니다 (확실하지 않습니다.) 그러나 false대부분의 (모두?) 구현에서 반환 될 것이라는 데 동의합니다 . 또한 답변을 참조하세요 @eerorika
walnut

0

이 표현식은 이 템플릿 연산자 와 일치합니다 (0은로 변환 됨 nullptr).

template <class T, class D>
bool operator<(const unique_ptr<T, D>& x, nullptr_t);

이것은 엄격한 순서 함수 std::less<unique_ptr<T,D>::pointer>()(p.get(), nullptr)와 같이 항상 false 인 std::less( demo )를 반환합니다 .


항상 반환되는 것은 아닙니다 false. 그것이 있는지 여부는 구현 정의 또는 지정되지 않은 것입니다. 아마도 false대부분의 (모두?) 현재 구현 에서는 항상 반환 됩니다.
호두

@walnut 표준이 말하는 내용에 대해 질문이 없으면 (예를 들어 언어 변호사 태그를 통해 ) 실질적인 관점에서 대답하려고합니다. 모든 실질적인 std::less수익 구현 false.
YSC

괜찮습니다. 나는 당신의 추론을 찾지 못했습니다 ( " std :: less는 엄격한 순서 functor입니다 "). 반환하지 않고 엄격한 주문이 될 수 있습니다 false. 실질적인 이유는 제로 포인터 값이 가능한 가장 낮은 주소 또는 해당 라인을 따라 표시되기 때문입니다.
호두
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.