2015-01-29 2 views
4

다음은 Boost.Python의 source code에서 미리보기입니다 :정의가없는 구조체 템플리트의 목적은 무엇입니까?

template <class T> struct null_ok; // how's it working? 

template <class T> 
inline null_ok<T>* allow_null(T* p) 
{ 
    return (null_ok<T>*)p; 
} 

은 앞으로 선언 구조체 null_ok에 대한 정의가 없다는 것을 유선, 그리고 null_ok는 템플릿 인수 T과는 아무 상관이 없습니다.

핸들 <> Y가 (null_ok는 (X))은 Y가

핸들 <> Y (X), NULL이 될 수 있도록 : Python wiki에서

일부 힌트 주어진 x는 null_ok의 결과가 아니며 결과는 NULL이 아닙니다. x가 NULL 인 경우 예외가 발생합니다

제가 위에서 언급 한 바와 같이 구조체 템플릿 (정의없이) 선언, null_ok이 목적을 달성 할 수있는 방법을 알아낼 수 없습니다?

+0

의견을 보내 주셔서 감사합니다. Marc. 나는 '앞으로 선언'을 확실히 알고 있습니다. 그러나이 선언에 대한 정의는 없습니다. 나는 그것이 어떤 메타 프로그래밍 목적을 가지고 있다고 생각하지만, 그것이 무엇인지 말할 수는 없다. @ MarcGlisse – nn0p

+0

예, 이전 제목은 혼란 스러웠다. 편집 됨. @MarcGlisse – nn0p

답변

4

요점은 포인터 유형의 원래 유형과 함께 "이 포인터가 null 이어도 괜찮습니다"라고 인코딩하는 것입니다.

포인터를 받아들이는 함수 템플릿은 null_ok<T>* 포인터를 인식하기 위해 오버로드되어 null 포인터에서는 오류가 발생하지 않습니다 (다시 T*으로 변환되는 동안).

null_ok에 대한 정의가 필요하지 않습니다. 불완전한 유형의 포인터를 가질 수 있기 때문에 사람들이 실수로 null_ok<int> a;과 같은 것을 작성하지 못하게합니다.

1

정확히 당신의 조각 아래 handle.hpp의 코드 (주석 광산)와 :

// this is a borrowed handle which can be null, 
// so increment refcount if p is not null 
// (xincref just does nothing in this case) 
template <class T> 
inline T* manage_ptr(detail::borrowed<null_ok<T> >* p, int) 
{ 
    return python::xincref((T*)p); 
} 

// the same - as stated in the doc, null_ok and borrowed are commutative 
template <class T> 
inline T* manage_ptr(null_ok<detail::borrowed<T> >* p, int) 
{ 
    return python::xincref((T*)p); 
} 


// this is a borrowed handle which cannot be null, so make sure p is not null 
// and increment refcount. 
template <class T> 
inline T* manage_ptr(detail::borrowed<T>* p, long) 
{ 
    return python::incref(expect_non_null((T*)p)); 
} 

// p is not borrowed and can be null - do nothing. 
template <class T> 
inline T* manage_ptr(null_ok<T>* p, long) 
{ 
    return (T*)p; 
} 

// p is not borrowed and cannot be null - make sure it isn't null indeed. 
template <class T> 
inline T* manage_ptr(T* p, ...) 
{ 
    return expect_non_null(p); 
} 

null_ok<T>이 코드를 컴파일하는 것은 단지 정의되지 선언, 그래서 완전 할 필요가 없습니다. 완성하면 컴파일러에 추가 작업이 추가됩니다.

관련 문제