2009-06-22 1 views
1

У меня есть умный тип указателя, и я хотел бы построить объект, который принимает указатель этого типа и счетчик (динамически вычисляемый во время выполнения) и выделяет достаточное количество памяти из стека, чтобы удержать, что многие экземпляры объекта умный указатель указывает на. Кажется, я не могу найти правильный синтаксис для достижения этого; Является ли это возможным?alloca() шаблонного массива типов: как это сделать?

Учитывая то, как этот

template<typename T> 
class PointerWrapper 
{ 
public: 
    PointerWrapper(T const * _pointer): m_pointer(_pointer) {} 
    typedef T Type; 
    T const * m_pointer; 
}; 

template<typename T> 
class SomeObject: public NoCopyOrAssign 
{ 
public: 
    SomeObject(void * _allocaBuffer, PointerWrapper<T> _source, int _count); 
}; 

Я хочу сделать что-то вроде этого:

void Test(PointerWrapper<int> _array, int _count) 
{ 
    SomeObject<int> object = MakeSomeObject(_array, _count); 
    // do some work with object 
}; 

код вызывающую следующий макрос не компилируется, поскольку компилятор не может вывести параметр шаблона SomeObject от _wrappedPtr поэтому испрашивается отсутствие параметра шаблона:

#define MakeSomeObject(_wrappedPtr, _runtimeCount) \ 
    SomeObject(alloca(sizeof(_wrappedPtr::Type)*_runtimeCount), \ 
        _wrappedPtr, _runtimeCount) 

Если используется функция templated для типа оболочки указателя, хотя компилятор неявно выводит типы, код, вызывающий его, не компилируется, потому что SomeObject намеренно определяет, но не реализует конструктор или оператор присваивания; даже если он сделал его компиляции не будет делать правильно, потому что память обеспечивается ALLOCA() немедленно выйти из области:

template<typename WrappedT> 
SomeObject<typename WrappedT::Type> MakeSomeObject 
    (WrappedT _pointer, uint _runtimeCount) 
{ 
    return SomeObject<typename WrappedT::Type> 
     (alloca(sizeof(typename WrappedT::Type)*_runtimeCount), 
     _pointer, _runtimeCount); 
} 

Я хотел бы, чтобы избежать передачи типа в макрос в качестве аргумента, так как в реальном коде это приведет к довольно длинным, трудно читаемым утверждениям в точке использования, однако я думаю, что это откат, если не будет ничего лучшего.

ответ

1

Не берите в глаза, отработал его; трюк состоял в том, чтобы объединить оба подхода:

template<typename WrappedT> 
SomeObject<typename WrappedT::Type> _MakeSomeObject 
    (void *_buffer, WrappedT _pointer, int _runtimeCount) 
{ 
    return SomeObject<typename WrappedT::Type> 
     (_buffer, _pointer, _runtimeCount); 
} 

template<typename WrappedT> 
int SizeT(WrappedT const _dummy) { return sizeof(typename WrappedT::Type); } 

#define MakeSomeObject(_wrappedPtr, _runtimeCount) \ 
     _MakeSomeObject(alloca(SizeT(_wrappedPtr)*_runtimeCount), \ 
      _wrappedPtr, _runtimeCount) 
Смежные вопросы