embrace POD type util they die
C++03的POD type,在C++11后由三个type_traits替代,standard layout, trivial, trivial copyable。 standard layout关注数据成员布局,而trivial关注行为。 我们首先看standard layout,
class Date{
int day;
int mouth;
public:
Date(){}
};
struct MyDate{
int d;
int m;
};
union DateMyDate{
Date date;
MyDate mydate;
};
int getMonth(const Date & d)
{
return DateMyDate(d).mydate.m;
}
int getday(Date* d)
{
return *reinterpret_cast<int*>(d);
}
这里Date和MyDate类型都是standard layout,但Date的成员都是私有的,MyDate的成员是共有的。我们可以通过创建union DateMyDate,访问他们的common initial sequence的成员任意成员。如getMonth访问第二个。对于第一个成员,可简便的用reinterpret_cast访问就可。
接着我们看trivial
class First{
public:
// ~First(){}
};
class Second{
public:
// Second(){}
int i;
};
union FS{
First f;
Second s;
};
constexpr void foo()
{
FS u;
u.s.i=1; //assign line
}
对于union ,上述的assign line, 要被赋值给非active member的字段,如果active member f的析构是trivial的,而非active member s的构造函数是trivial的,那么将赋值成功并立刻将active member转换为s;如果约束不满足,将是UB,反注释掉First的析构或Second的构造将编译失败。
最后我们看看trivial copyable,这里指对象可以使用memmove memcopy来操作。对于trivail copyable,要求所有eligible的copy, copy assign,move,move assign以及析构必须是trivial的,且eligible析构不能被delete,注意这里没有对这些函数是否public protected or private的要求,
class A{
private:
A(const A&)=delete;
A& operator=(const A&)=delete;
A(A&&)=delete;
A& operator=(A&&)=delete;
~A()=default;
};
static_assert(std::is_trivially_copyable_v<A>);
这里的A是满足trivial copyable要求的。