2011-04-11 2 views
4
template<class T, typename U> ptrdiff_t foo(T U::* m) 
{ 
    // return offset 
} 

이 컨텍스트에서 필드 'm'의 오프셋을 어떻게 얻을 수 있습니까? 나는 컴파일 타임 표현을 선호한다.멤버에 대한 포인터의 오프셋

미리 도움을 청하십시오. 감사합니다.

+0

이것은 아마도 나쁜 아이디어입니다. 대신에 포인터를 멤버 유형으로 사용하는 것이 어떻습니까? – GManNickG

+0

흠, 정확히 무엇을 의미합니까? 위의 매개 변수는 포인터를 구성원으로 ... – 0xbadf00d

+0

맞고 그대로 두십시오. 오프셋은 단순히 대부분의 C++ 클래스 (POD가 아닌 클래스)에 사용하기에는 너무 원시적입니다. – GManNickG

답변

3

offsetof() 매크로를 찾고있는 것처럼 들립니다.

+0

멤버 포인터 만 사용하여 'offsetof'를 호출하는 것은 유효하지 않으며 멤버 이름 만 사용할 수 있습니다. (많은 구현에서 작동 할 수도 있지만, 이런 종류의 것이 얼마나 모호한지를 고려하면 컴파일러 업데이트에서 깨질 수 있습니다.) – Yakk

+0

안녕하세요 @Yakk. 무슨 뜻인지 잘 모르겠다. "offsetof"(위의) 단어를 클릭하면 매크로의 문서로 이동합니다. 그것은 내게 유쾌 해 보인다. "멤버 포인터"는 포인터 인 구조체의 멤버를 의미합니까? 예 : struct s {int i; char * p; }; size_t n = offsetof (struct s, p); –

4

@ 마이클 J

답장을 보내 주셔서 감사합니다. 이것은 정확히 내가 원하는 것이 아니지만, 저에게 영감을줍니다.

template<class T, typename U> 
std::ptrdiff_t member_offset(U T::* member) 
{ 
    return reinterpret_cast<std::ptrdiff_t>(
     &(reinterpret_cast<T const volatile*>(NULL)->*member) 
    ); 
} 
+2

여기서 널 포인터를 참조 해제합니다. 라이브러리를 구현하지 않는 한 offsetof 매크로에서 사용할 특별한 배포본을 얻지 않는 한 허용되지 않습니다. 누군가 나를 -1로 때렸다. –

+0

offsetof 매크로는 다음과 같습니다. (size_t) & reinterpret_cast ((((s *) 0) -> m)). 차이점이 뭐야? – 0xbadf00d

+2

차이점은 offsetof는 ** 특정 컴파일러 **에 해당하며, 라이브러리 디자이너 만이 컴파일러 작성자와 특별 계약을 체결했기 때문입니다. 그런 다음 효과가있을 수 있습니다. 다른 컴파일러에서는 offsetof가 특수한 __builtin_offsetof 함수로 대신 사용됩니다. 아니면 다른 속임수. 라이브러리에서 offsetof가있는 주된 이유는 이식 할 수 없기 때문에 컴파일러에서 특별한 지원이 필요하다는 것입니다. –

0

간단한 대답은 할 수 없다는 것입니다. 유형 U가 POD 인 경우 offsetof 매크로를 사용할 수 있지만 형식이 POD가 아닌 경우 공식적으로 정의되지 않음 : 컴파일러에 따라 컴파일 오류가 발생하거나 잘못되었습니다. 일부 결과는 입니다. 그리고 당신은 멤버에 대한 포인터에 그것을 사용할 수 없습니다. 은 클래스 이름으로 호출해야하고, 구성원 이름은 입니다.

관련 문제