2010-04-08 3 views
3

free() 일 때 실제로 객체의 메모리를 해제하지 않고 대기열에 보유하고 새로운 객체가 요청되면 이전에 할당 된 객체를 반환하는 일반 할당 자 클래스를 작성하려고합니다. 이제, 내 머리를 감쌀 수없는 것은 allocator를 사용할 때 (적어도 variadic 템플릿을 사용하지 않고) 객체의 생성자에 인수를 전달하는 방법입니다. 나는이 같은 외모와 함께 제공되는 ALLOC() 함수 :가변 배열 템플릿이없는 일반 할당 기 클래스?

template <typename... T> 
inline T *alloc(const &T... args) { 
    T *p; 

    if (_free.empty()) { 
     p = new T(args...); 
    } else { 
     p = _free.front(); 
     _free.pop(); 

     // to call the ctor of T, we need to first call its DTor 
     p->~T(); 
     p = new(p) T(args...); 
    } 
    return p; 
} 

는 여전히 오늘의 C++ (그리고 가변 인자 템플릿을 지원하지 않는 GCC의 이전 버전)와 호환하는 코드가 필요합니다. 임의의 양의 인수를 객체 생성자에 전달하는 다른 방법이 있습니까?

template<class T> 
T* alloc() { 
    /* ... */ 
} 

template<class T, class A0> 
T* alloc(const A0& a0) { 
    /* ... */ 
} 

/* ... */ 

당신은 비록 preprocessor metaprogramming을 사용할 수 있습니다 : 당신은 당신이 의사 가변 인자 템플릿을 제공 할 필요가 사전 C++ 0X 컴파일러를 대상으로 할 필요가

답변

3

, 당신은 모든 필요한 인수에 대응하기위한 템플릿 기능을 제공해야 즉, 회귀를 다루기 위해 Boost.Preprocessor을 사용하거나 단순히 간단한 스크립트를 사용하여 함수를 생성하면됩니다.

#include <boost/preprocessor/arithmetic/inc.hpp> 
#include <boost/preprocessor/repetition/enum_binary_params.hpp> 
#include <boost/preprocessor/repetition/enum_params.hpp> 

template<class T> 
T* alloc() { 
    return new T; 
} 

#define FUNCTION_ALLOC(z, N, _) \ 
    template<class T, BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), class T)> \ 
    T* alloc(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(N), const T, &p)) { \ 
    return new T(\ 
     BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), p) \ 
    ); \ 
    } 

BOOST_PP_REPEAT(10, FUNCTION_ALLOC, ~) 

#undef FUNCTION_ALLOC 

이 당신에게 최대 10 개 인수 alloc() 템플릿 함수를 생성 후

는 Boost.PP를 사용하여 간단한 예이다.

+0

가 도움을 높일 수 있습니까? – UncleBens

+0

네, Boost.PP가 도움이됩니다. @GMan은 어딘가에서 좋은 예가 있었고 그것을 파헤 치려고합니다. –

+0

전 부스트 프리 프로세서 (Boost Preprocessor)를 많이 사용하지만 사이트에 많은 것을 넣지는 않았다고 생각합니다. Matthieu는 최근에 한 가지를했습니다. http://stackoverflow.com/questions/2597586/simplifying-templates/2598283#2598283 – GManNickG

0

문제에 대한 사전 C++ 11 해결책은 인수의 복사본을 만드는 간단한 alloc 함수를 제공하는 것입니다. 이것이 C++ 03 할당 자 및 모든 컨테이너가 20 년 이상 근무한 방식입니다.

template <typename T> 
inline T *alloc(const &T arg) { 
    T *p; 

    if (_free.empty()) { 
     p = new T(arg); 
    } else { 
     p = _free.front(); 
     _free.pop(); 

     // to call the ctor of T, we need to first call its DTor 
     p->~T(); 
     p = new(p) T(arg); 
    } 
    return p; 
} 

을 그리고 당신은 그것을 전화 : 코드에 적용이된다

// copy construct T into the allocator's memory: 
instance_of_your_allocator.alloc(T(1, 2, 3)); 

이 방법의 단점은 사용할 수 중 복사 생성자를 필요로한다는 것이다, 그 잠재적으로 값 비싼 작동.

하나 더 예 :

vector<T> vec; 
vec.push_back(T(1, 2, 3)); // C++03 way, uses move cons-tor in C++11 if possible. 
vec.emplace_back(1, 2, 3); // C++11 way, constructs in-place