alloca () шаблонного массива типов: как это сделать? - PullRequest
1 голос
/ 22 июня 2009

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

Учитывая что-то вроде этого

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)

Если используется функция, ориентированная на тип-оболочку указателя, хотя компилятор может неявно определять типы, вызывающий его код не компилируется, поскольку 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 Ответ

1 голос
/ 22 июня 2009

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

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 )
...