템플릿 프로그래밍 : 함수자

아 이제 함수자를 이용하거나 구현하는건 깨달아버린 느낌이다.


/// 레이어를 이용해 객체들을 관리하는 템플릿 클래스
template<class T, class Tr = ContainerObjectReleaser<T> >
class ContainerTmpl
{
public:
    typedef std::vector
<T> Layer;    
    typedef std::map
< int, Layer > Container;

private:
    Container    _container;

public:
    ContainerTmpl();
   
virtual ~ContainerTmpl();

    void    Release();
   
void    ReleaseLayer(int key);

    template <class D>
   
bool    DoAll(D d);

    template <class D>
   
bool    DoLayer(int key, D d);
};

#include Container.inl



대략 이런 느낌의 템플릿 코드를 만들고 컨테이너에 담아넣은 오브젝트들을 해제하는 함수자를 이런식으로 구현


/// PrimitiveMesh를 해제시키는 함수자
struct ReleaserPrimitiveMesh
{
public:
   
bool operator()(lgn::PrimitiveMesh* p)
    {
        p
->Release();
        delete p;
       
return true;
    }
};



그리고 선언하고 사용하다가 Release() 를 호출하면 위의 함수자를 이용해서 객체들을 해제하도록 한다.


ContainerTmpl<lgn::PrimitiveMesh*, ReleaserPrimitiveMesh>    _containerRender;

_containerRender.Release();

아니면 ContainerTmpl 의 DoAll 함수에 함수자를 직접 지정해서 사용하도록 하던지.
우선 함수자를 먼저 구현하고…


struct RenderPrimitiveMesh
{
private:
    lgn::Renderor
* _r;

public:
    RenderPrimitiveMesh( lgn::Renderor
& r )
        : _r(
&r)
    {
    }

    bool operator()(lgn::PrimitiveMesh* p)
    {
        p
->Render(*_r);
       
return true;
    }
};


그리고 필요에 따라 DoAll 함수를 호출한다.


_containerRender.DoAll( RenderPrimitiveMesh(_r) );

DoAll 의 내부 코딩은 대략 이런식


template <class T, class Tr>
template <class D>
bool ContainerTmpl<T, Tr>::DoAll(D d)
{
    Container::iterator end
= _container.end();
   
for( Container::iterator i = _container.begin(); i != end; ++i )
    {
        DoLayer( i
->first, d );
    }
   
return true;
}

template <class T, class Tr>
template
<class D>
bool ContainerTmpl<T, Tr>::DoLayer(int key, D d)
{
    Layer
* layer = GetLayer(key);

    Layer::iterator i = layer->begin();
    Layer::iterator end
= layer->end();
   
while( i != end )
    {
       
if( d( *i ) == false )
           
throw Exception;
       
++i;
    }
   
return true;
}


이거 꽤 재미있는데. 나중에 이런식으로 잘되어있는거 코딩할때는 상당히 재미있겠군. 내가 저런 형태로 라이브러리를 만든다면 대략 토나오는 느낌이겠지만.
예전엔 상당히 아리까리 했는데 오늘은 꽤나 명확한 느낌으로 다가온다.

관련내용.


  • EffectiveSTL38 – 함수자 클래스는 값으로 전달되도록 설계하자.
  • EffectiveSTL39 – 술어 구문은 순수 함수로 만들자.
  • EffectiveSTL40 – 함수자 클래스는 어댑터 적용이 가능하게(adaptable) 만들자.
  • EffectiveSTL41 – ptr_fun, mem_fun, mem_fun_ref 의 존재에는 분명한 이유가 있다.
  • EffectiveSTL42 – less<T>는 operator< 의 의미임을 꼭 알아두자.

    외 링크에 적혀있는 내용의 출처는 Effective STL.