2009-06-22 5 views
1

J'ai un type de pointeur intelligent, et voudrais construire un objet qui prend un pointeur de ce type et un nombre (calculé dynamiquement à l'exécution) et alloue assez de mémoire de la pile pour contenir plusieurs instances de l'objet pointe vers. Je n'arrive pas à trouver la bonne syntaxe pour y parvenir; c'est possible?alloca() d'un tableau de types: comment faire cela?

Étant donné quelque chose comme ça

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); 
}; 

Je veux faire quelque chose comme ceci:

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

code invoquant la macro suivante ne compile pas, parce que le compilateur ne peut pas en déduire le paramètre de modèle de SomeObject de _wrappedPtr se plaint donc que le paramètre de modèle est manquant:

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

Si une fonction modèle sur le type wrapper de pointeur est utilisée, bien que le compilateur puisse déduire les types implicitement, le code l'invoquant ne compile pas car SomeObject définit délibérément mais n'implémente pas un constructeur de copie ou un opérateur d'affectation; même si elle a effectivement compilé ce ne serait pas faire la bonne chose parce que la mémoire fournie par alloca() serait immédiatement sortir du champ:

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); 
} 

Je voudrais éviter de passer le type dans la macro comme argument depuis dans le code réel, cela se traduirait par des instructions assez longues et difficiles à lire au point d'utilisation, mais je suppose que c'est une solution de repli si rien de mieux n'est possible.

Répondre

1

Peu importe, ça a fonctionné; l'astuce consistait à combiner les deux approches:

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) 
Questions connexes