类型模板化数组的 alloca():如何做到这一点?

发布于 2024-07-25 23:51:27 字数 1513 浏览 9 评论 0原文

我有一个智能指针类型,并且想要构造一个对象,该对象采用该类型的指针和计数(在运行时动态计算),并从堆栈中分配足够的内存来保存智能指针指向的对象的许多实例。 我似乎找不到正确的语法来实现这一点; 是否可以?

给定这样的事情,

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

调用以下宏的代码无法编译,因为编译器无法从 _wrappedPtr 推导出 SomeObject 的模板参数,因此抱怨模板参数丢失:

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

我想避免将类型作为参数传递到宏中,因为在实际代码中这会导致在使用时使用相当冗长、难以阅读的语句,但是我想如果没有更好的办法的话,这是一个后备方案。

I have a smart pointer type, and would like to construct an object that takes a pointer of that type and a count (dynamically calculated at runtime) and allocates enough memory from the stack to hold that many instances of the object the smart pointer points to. I can't seem to find quite the right syntax to achieve this; is it possible?

Given something like this

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

I want to do something like this:

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

Code invoking the following macro doesn't compile, because the compiler cannot deduce SomeObject's template parameter from _wrappedPtr so complains that the template parameter is missing:

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

If a function templated on the pointer wrapper type is used, although the compiler can deduce the types implicitly, code invoking it doesn't compile because SomeObject deliberately defines but does not implement a copy constructor or assignment operator; even if it did compile it would not do the right thing because the memory provided by alloca() would immediately go out of scope:

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

I'd like to avoid passing the type into the macro as an argument since in the real code this would result in quite lengthy, hard-to-read statements at the point of use, however I guess that is a fallback if nothing better is possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

︶葆Ⅱㄣ 2024-08-01 23:51:27

没关系,解决了; 诀窍是将这两种方法结合起来:

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 )

Never mind, worked it out; the trick was to combine both approaches:

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 )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文