Boost assert.hpp 파일에서 P :: ************는 무엇을 의미합니까?


80

부스트 / MPL / assert.hpp , 나는 이런 식으로 뭔가를 보았다 :

template<class Pred>
struct eval_assert {
    typedef typename extract_assert_pred<Pred>::type P;
    typedef typename P::type p_type;
    typedef typename ::boost::mpl::if_c<p_type::value,
        AUX778076_ASSERT_ARG(assert<false>),
        failed ************ P::************
    >::type type;
};

첫 번째 ************가 struct의 포인터가 실패한 것으로 처리 될 수 있다면 P::************실제로는 나에게 의미가 없습니다. 이 표준 C ++입니까?


38
Pointerception ...
Jakub Arnold

5
@deviantfan 프로덕션 코드에서? 당신은 놀랄 것입니다. ;) 그러나 여기서 요점은 P존재하지 않을 것이라는 매우 높은 수준의 확신을 가지고 의 멤버를 참조하려고 시도하여 컴파일 실패를 유발하는 것입니다. (C ++ 11에서는 아마도 static_assert(false)대신 사용 하겠지만 물론 Boost는 C ++ 11 이전 버전으로 이식 가능해야합니다.)
cdhowie

4
참고 : 12 레벨 포인터는 아마도 C 표준에서 요구하는 최소값과 관련이있을 것입니다.
TC

29
@PaulDraper 그것은 실제로 hunter2hunter2hunter2hunter2여기에서 읽고 있습니다
sehe

5
포인터에 대한 포인터에 대한 포인터에 대한 포인터에 대한 포인터에 대한 포인터에 대한 포인터에 대한 포인터에 대한 포인터에 대한 포인터에 대한 포인터에 대한 포인터에 대한 포인터에 대한 포인터에 대한 포인터에 대한 유형 P의 멤버에 대한 포인터에 대한 포인터
Kai

답변:


100

이 코드의 요점은 컴파일러가 "보이는"오류 메시지를 생성하도록 돕는 것입니다.

이전 static_assert시대에는 템플릿이 많은 코드를 컴파일하면 한 번의 실수로도 ~ 100 줄의 오류 메시지를 쉽게 생성 할 수 있었으며 이러한 줄의 99 %는 종종 무의미했습니다.

10 개의 포인터 트릭은 실제 오류를 지적하는 데 유용합니다. 예를 들면 다음과 같습니다.

 BOOST_STATIC_ASSERT((std::is_same<T,U>));

with T=void*U=char*gcc로 컴파일하면 ~ 10 개의 오류 줄이 생성되지만 관련 줄은 쉽게 볼 수 있습니다.

error: no matching function for call to ‘assertion_failed(mpl_::failed************ std::is_same<void*, char*>::************)’

45

그것은 포인터-포인터-투 -...- 멤버 유형 P의 멤버이며, 여기서 멤버는 포인터-투-포인터 -...- 유형의 데이터 멤버입니다 failed.

이 경우 목표는 P존재하지 않을 확률이 매우 높은 의 멤버를 참조하여 컴파일이 실패 하도록 만드는 것입니다. C ++ 11에서는 static_assert대신 사용 하지만 물론 Boost는 C ++ 11 이전 방언으로 이식 할 수 있어야합니다.


19

F P::*"" P유형의 멤버에 대한 포인터 F입니다.

F P::**" P유형의 멤버에 대한 포인터에 대한 포인터 F"입니다.

더 많은 *s는 앞에 더 많은 "포인터"를 추가합니다.

이 경우, Fis failed ************, 즉 "포인터에 대한 포인터 ...에 대한 포인터 failed".

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.