반응형

BLOG main image



아래 포스트는 http://cafe.naver.com/ecpp 에서 부분을 조금씩 발췌한 글입니다 (보기 편하게 색깔등만 편집되었습니다)









boost::mpl 이 할줄 아는 것이라고는 결국엔 컴파일 시점에 '타입 추론' 과 '상수값 추론' 밖에 없습니다.





일단 간단한 예제를 한번 보겠습니다.


ex1)


#include <boost/mpl/aux_/test.hpp>

 

MPL_TEST_CASE()
{
       MPL_ASSERT(( boost::is_same<char, char> ));
       //MPL_ASSERT(( boost::is_same<int, char> ));
}



실행시 별로 어려움은 없으리라 생각됩니다.

 

  • 일단, vc7.1 ( 2003 버전 ) 서는 위의 코드를 컴파일하게되면 에러가 발생할 수 있습니다.

    MPL_ASSERT 의 내부구현에서 컴파일에러를 발생하는 데 그 원인은 정확하게 짚어보지는 않았습니다.

    매크로를 처리하는데 있어서 vc7.1 이 버그가 있다고만 추측만 할 뿐입니다.

    컴파일을 성공시키기 위해서는 Project Setting - C/C++ - 일반 - 디버깅정보형식 을 ZI 말고 Zi 로 바꿔주시면 컴파일시에 컴파일러는

    아무런 불평을 하지 않습니다. 물론 2005 버전에서는 아무런 문제가 없습니다.



MPL_ASSERT 는 BOOST_MPL_ASSERT 를 재정의한 것일 뿐입니다. AssistX 란 툴을 쓰신다면 Alt+G 키로 정의를 금방 볼수 있죠.

 

다른 것은 직접 읽어보시면 될터이지만, 쉽게 이해가 가지 않는 부분이 파라메타가 "Boolean nullary Metafunction" 이어야 한다고



 "불린 널러리 메타함수" 가 무엇일까요?




  • 메타함수( Metafunction ) 

    공개적으로 접근할 수 있는 type 이라는 이름의 내포된 결과형식을 가진,

    모든 템플릿 매개변수들이 형식인 클래스템플릿 혹은 클래스

       (써비왈 - 메타함수는 boost::mpl 에서 상당히 중요한 개념입니다. C++ Meta Programming 에서는 메타함수는 

       boost::mpl 의 중심적인 추상이란 표현을 하였는데요. 대략 의미는 boost::mpl 의 대부분의 것들이 type 을 내포하고, 

       그 대부분의 것들이 메타함수라는 뜻으로 표현한 듯 싶습니다.)

  • 무항 메타함수( Nullary Metafunction )

    템플릿 매개변수를 받지않는 메타함수

    (써비왈 - 템플릿클래스가 아니고 일반 클래스라면 무항메타함수이겠죠? 또 전체특수화가 된 클래스템플릿이라면 역시 무항메타함수입니다.)

  • 수치메타함수( Numerical Metafunction )

    수치값을 감싸는 래퍼형식을 돌려주는 메타함수, 편의상 많은 수치 메타함수들은 내포된 ::value 멤버를 직접 제공한다.

    그런 메타함수들의 다음과 같은 좀 더 일반적읜 표현을 사용하는 대신,

    some_numerical_metafunction<Arg>::type::value  다음처럼 수치결과에 직접 접근할 수 있다.

    some_numerical_metafunction<Arg>::value


위의 정의된 내용들은 C++ Meta Programming 에서 발췌한 것입니다. 좀 더 구체적으로 접근을 해볼까요?

 


ex1)


#include <boost/mpl/aux_/test.hpp>

 

MPL_TEST_CASE()
{
       MPL_ASSERT(( boost::is_same<char, char> ));
       //MPL_ASSERT(( boost::is_same<int, char> ));
}


위의 ex1 에서 is_same 은 Boolean Nullary Metafunction 인가요? 왠지 Nullary 같지는 않죠?


is_same 의 정의를 보면 type 이라는 멤버가 있습니다. 메타함수인것은 확실히 맞습니다. 그렇지만 Nullary 는 아닙니다.


is_same::type 이 Boolean Nullary Metafunction 입니다. 즉 is_same 이 리턴해주는(::type) 타입이 


Boolean Nullary Metafunction 이라는 것으로 보셔야 합니다.






BOOST_MPL_ASSERT 는 boolean nullary metafunction 을 인수로 받게 됩니다.


  • boolean - ::value 는 true or false 여야 한다.

    nullary - 템플릿인수는 특화되었거나 없어야 한다.

    metafunction - ::type 이 존재해야한다.



   

즉 아래와 같은 구현도 boolean nullary metafucntion 이 될 수 있습니다.

 

struct Boolean_nullary_Metafunction_true
{
     typedef Boolean_nullary_Metafunction_true type;
     static const bool value = true;
};


struct Boolean_nullary_Metafunction_false
{
    typedef Boolean_nullary_Metafunction_false type;
    static const bool value = false;
};

 

BOOST_MPL_ASSERT(( Boolean_nullary_Metafunction_true )); // 컴파일 에러 없음.












#include <boost/mpl/assert.hpp>              // BOOST_MPL_ASSERT 땜에 필요하죠.

#include <boost/mpl/int.hpp>                   // boost::mpl::int_ 를 정의하고 있는 파일입니다.

#include <boost/type_traits/is_same.hpp>  // type_traits 란 영역에 존재한다고 강조했었습니다.



namespace mpl = boost::mpl;                    // boost::mpl 은 좀 길죠?



 

void main()

{

       // 1. 컴파일에서 아무 문제가 없습니다.

      BOOST_MPL_ASSERT(( boost::is_same< bool, bool > ));

 

      // 2. 컴파일에서 에러로그가 발생하죠? 컴파일에러로그로 정보를 출력해줍니다.

      BOOST_MPL_ASSERT(( boost::is_same< bool, int > ));     

      

      // 3. 인수로 타입을 넣어야 하는데 값을 넘겨주죠? 사용법자체가 잘못되었죠. 엄청난 에러메세지들이 뜰겁니다.

      BOOST_MPL_ASSERT(( boost::is_same< 2, 2 > ));

 

      // 4. 이것은요? 클래스타입을 넘겼기 때문에 아무런 문제가 없습니다.

      BOOST_MPL_ASSERT(( boost::is_same< mpl::int_<2>, mpl::int_<2> > ));

 

      // 5. 이것은 2.와 같이 is_same<> 에서 넘겨준 두개의 타입이 다르다는 의미로 컴파일에러가 납니다.

      BOOST_MPL_ASSERT(( boost::is_same< mpl::int_<2>, mpl::int_<3> > ));

}




 

boost::mpl::int_ 는 한번도 본적이 없었는데요. boost::mpl::bool_ 과 거의 같은 구조로 정의되어있다고 보시면 됩니다.

int 란 성격상 추가된 함수가 존재하는데 prior, next 가 존재합니다. 실행시점의 연산자 ++, -- 정도로 보시면 됩니다.





 







반응형

'메타프로그래밍 > Boost::' 카테고리의 다른 글

Boost::foreach  (0) 2013.01.29
boost::random  (0) 2013.01.29
boost::thread  (0) 2012.12.25
boost::weak_ptr  (0) 2012.11.24
boost::shared_ptr  (0) 2012.11.18

+ Recent posts