아래 포스트는 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 |