gpt4 book ai didi

c++ - placement new 基于模板 sizeof()

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:30:08 24 4
gpt4 key购买 nike

这在 C++11 中合法吗?使用最新的英特尔编译器编译并且似乎可以工作,但我只是觉得它是侥幸。

 class cbase
{
virtual void call();
};

template<typename T> class functor : public cbase
{
public:
functor(T* obj, void (T::*pfunc)())
: _obj(obj), _pfunc(pfunc) {}

virtual void call()
{
(_obj)(*_pfunc)();
}
private:
T& _obj;
void (T::*_pfunc)();
//edited: this is no good:
//const static int size = sizeof(_obj) + sizeof(_pfunc);
};

class signal
{
public:
template<typename T> void connect(T& obj, void (T::*pfunc)())
{
_ptr = new (space) functor<T>(obj, pfunc);
}
private:
cbase* _ptr;
class _generic_object {};
typename aligned_storage<sizeof(functor<_generic_object>),
alignment_of<functor<_generic_object>>::value>::type space;
//edited: this is no good:
//void* space[(c1<_generic_object>::size / sizeof(void*))];

};

具体来说,我想知道 void* space[(c1<_generic_object>::size / sizeof(void*))];确实会为 c1 的成员对象(_obj 和 _pfunc)提供正确的大小。 (不是)。

编辑:因此,经过更多研究后,似乎以下内容(更多?)是正确的:

typename aligned_storage<sizeof(c1<_generic_object>), 
alignment_of<c1<_generic_object>>::value>::type space;

然而,在检查生成的程序集时,使用带有此空间的新位置似乎会阻止编译器优化对“new”的调用(这似乎发生在仅使用常规“_ptr = new c1;”时)

EDIT2:更改代码以使意图更清晰一些。

最佳答案

const static int size = sizeof(_obj) + sizeof(_pfunc); 将给出成员大小的总和,但这可能与包含的类的大小不同那些成员。编译器可以自由地在成员之间或最后一个成员之后插入填充。因此,将成员的大小加在一起近似于该对象可能的最小值,但不一定给出具有这些成员的对象的大小。

事实上,对象的大小不仅取决于其成员的类型,还取决于它们的顺序。例如:

struct A { 
int a;
char b;
};

对比:

struct B { 
char b;
int a;
};

在很多情况下,A 会小于B。在 A 中,ab 之间通常没有填充,但在 B 中,通常会有一些填充(例如,对于 4 字节的 int,ba 之间通常会有 3 个字节的填充)。

因此,您的空间可能没有足够的...空间来容纳您试图在init中创建的对象。

关于c++ - placement new 基于模板 sizeof(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16996472/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com