템플릿 인수로서 멤버 기능에 대한 포인터를 전달합니다. 이것이 왜 작동합니까?

StackOverflow https://stackoverflow.com/questions/1882740

문제

100%가 사용 케이스에 효과가있는 코드가 있습니다. 누군가가 어떻게 그리고 왜 작동하는지 설명 할 수 있는지 궁금합니다.

스레딩과 네트워크 통신을 처리하는 일부 코드와 라이브러리 사용자가 서버에서 수신 된 데이터를 사용자에게 전달하는 템플릿 클래스가 있습니다.

template <class Bar,
          class Baz,
          class BazReturnType,
          void (Bar::*BarSetterFunction)(const BazReturnType &),
          BazReturnType (Baz::*BazGetterFunction)(void) const>
class Foo
{
    Foo( Bar *bar )
        : m_bar(bar)
    {
    }

    void FooMemberFunction( const Baz *baz )
    {
        boost::bind( BarSetterFunction, m_bar,
                     boost::bind( BazGetterFunction, baz )() ) ();
    }

    Bar *m_bar;
};

이 템플릿은 BAR 유형과 BAZ 유형에 따라 라이브러리에서 인스턴스화되고 사용됩니다.

typedef Foo<MyBar,
            MyBaz,
            ReturnTypeFromBazGetterFunction,
            &MyBar::ActualSetterFunction,
            &MyBaz::ActualGetterFunction >
    MyFoo;

MyBar *bar = new MyBar;
MyBaz *baz = new MyBaz;
MyFoo *f = new MyFoo( bar );
f->FooMemberFunction( baz );

이 모든 것이 작동하며 Boost :: Bind는 Getter/Setter 기능을 호출하여 데이터를 가야 할 위치를 전달합니다. 이 경우와 같은 템플릿 인수로서 멤버에 포인터를 전달하는 방법과 이유는 무엇입니까?


의견에 대한 응답으로, 나는 멤버 함수에 대한 포인터가 유효한 템플릿 인수라는 것을 깨닫지 못했습니다. 그것은 내가 전에 "야생에서"본 것이 아닙니다. 나는 그것을 시도했고 그것은 효과가 있었지만 나는 그것을 기대하지 않았다.

도움이 되었습니까?

해결책

"표준이 그렇게 말하기 때문에"보다 그렇게 할 수있는 이유가 더 나은 설명이 있다고 생각합니다.

그것이 작동하는 이유는 포인터 투-멤버가 컴파일 시간에 알려진 일정한 값이기 때문입니다 (포인터 투 인원은 클래스 시작부터 멤버의 오프셋입니다). 따라서 다른 정수 상수와 마찬가지로 템플릿의 매개 변수로 사용될 수 있습니다.

반면, 일반 포인터는 런타임에만 존재하는 메모리 레이아웃에 의존하기 때문에 시간 상수를 컴파일하지 않습니다. 템플릿 인수가 될 수 없습니다.

다른 팁

"왜 무엇 작동합니까? ", 그것은 그것이 작동한다는 사실이 어떻게 든 당신에게 놀랍다는 것을 암시합니다. 설명하지 않으면 질문에 대답하는 것은 불가능합니다. 당신은 놀랍습니다.

왜 작동합니까? 언어 사양은 그것이 효과가 있다고 명시 적으로 말하기 때문입니다. 우려 사항을 더 자세히 설명 할 때까지 다른 대답은 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top