업데이트 : C ++ 11에서는 std::addressof
대신 사용할 수 있습니다 boost::addressof
.
먼저 비트에서 컴파일러 작업을 빼고 Boost에서 코드를 복사 해 보겠습니다.
template<class T>
struct addr_impl_ref
{
T & v_;
inline addr_impl_ref( T & v ): v_( v ) {}
inline operator T& () const { return v_; }
private:
addr_impl_ref & operator=(const addr_impl_ref &);
};
template<class T>
struct addressof_impl
{
static inline T * f( T & v, long ) {
return reinterpret_cast<T*>(
&const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
}
static inline T * f( T * v, int ) { return v; }
};
template<class T>
T * addressof( T & v ) {
return addressof_impl<T>::f( addr_impl_ref<T>( v ), 0 );
}
함수에 대한 참조를 전달하면 어떻게됩니까 ?
참고 : addressof
함수에 대한 포인터와 함께 사용할 수 없습니다
C ++에서 if void func();
가 선언되면 func
인수를 사용하지 않고 결과를 반환하지 않는 함수에 대한 참조입니다. 기능이 참조는 소소 함수에 대한 포인터로 변환 할 수있다 -에서 @Konstantin
: 13.3.3.2 양쪽에 따르면 T &
및 T *
기능과 구별된다. 첫 번째는 Identity 변환이고 두 번째는 "정확한 일치"순위 (13.3.3.1.1 표 9)를 갖는 함수-포인터 변환입니다.
함수 참조 통과 addr_impl_ref
의 선택에 대한 과부하 해상도 모호성가, f
더미 인수에 확실히 해결, 0
이며, int
제 1 및 승격 될 수있다 long
(적분 변환)이.
따라서 우리는 단순히 포인터를 반환합니다.
변환 연산자를 사용하여 형식을 전달하면 어떻게됩니까?
변환 연산자가 a T*
를 산출 하면 모호함이 있습니다. f(T&,long)
두 번째 인수에는 Integral Promotion이 필요하지만 f(T*,int)
변환 연산자는 첫 번째에 호출됩니다 (@litb 덕분)
때이다 addr_impl_ref
. C ++ 표준의 의무의 차기 변환 순서가 가장 한 사용자 정의 변환에 포함 할 수있다. 형식을 래핑하고 addr_impl_ref
변환 순서를 이미 사용함으로써 형식과 함께 제공되는 변환 연산자를 "비활성화"합니다.
따라서 f(T&,long)
과부하가 선택됩니다 (및 Integral Promotion이 수행됨).
다른 유형은 어떻게됩니까?
따라서 f(T&,long)
유형이 T*
매개 변수 와 일치하지 않기 때문에 과부하가 선택 됩니다.
참고 : Borland 호환성과 관련하여 파일의 설명에서 배열은 포인터로 붕괴되지 않지만 참조로 전달됩니다.
이 과부하는 어떻게됩니까?
operator&
오버로드되었을 수 있으므로 유형에 적용하지 않기를 원합니다 .
reinterpret_cast
이 작업에 사용될 수있는 표준이 보장 됩니다 (@Matteo Italia의 답변 : 5.2.10 / 10 참조).
Boost는 컴파일러 경고를 피하기 위해 const
및 volatile
한정자를 사용하여 멋진 기능을 추가합니다 (및 적절하게 사용 const_cast
하여 제거).
- 캐스트
T&
로char const volatile&
- 스트립
const
및volatile
&
주소를 취하기 위해 연산자를 적용
- 다시 캐스트
T*
const
/ volatile
저글링은 마술의 약간이지만 (오히려 4 과부하를 제공하는 대신) 작업을 단순화한다. 이후주의 T
규정되지 않은, 우리가 통과하는 경우는 ghost const&
, 다음 T*
입니다 ghost const*
따라서 예선 정말 손실되지 않았습니다.
편집 : 포인터 오버로드는 함수에 대한 포인터에 사용됩니다. 위의 설명을 약간 수정했습니다. 그래도 왜 필요한지 이해하지 못합니다 .
다음의 이데 오네 출력은 이것을 요약합니다.