考虑这个简单的程序
#include <iostream>
struct A
{
int x1234;
short x56;
char x7;
};
struct B : A
{
char x8;
};
int main()
{
std::cout << sizeof(A) << ' ' << sizeof(B) << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这打印8 12.即使B可以在不破坏对齐要求的情况下打包成8个字节,但它却占用了贪婪的12个字节.
这样会很好sizeof(B) == 8,但答案是结构的大小是否必须
是该结构对齐的精确倍数?表明没有办法.
因此,当以下时我感到惊讶
struct MakePackable
{
};
struct A : MakePackable
{
int x1234;
short x56;
char x7;
};
struct B : A
{
char x8;
};
Run Code Online (Sandbox Code Playgroud)
印刷8 8 …
我有一个模板化的结构,它有一个带有额外浮点数的变体,如下所示:
template <bool HasFloat>
struct Foo {
std::vector<int> a;
float b; // Not needed if HasFloat is false
};
Run Code Online (Sandbox Code Playgroud)
为了节省内存(是的,它很重要)我想省略浮点数,如果HasFloat是假的.由于struct最好的方式还有很多其他东西会是这样的:
using B = typename std::conditional<HasFloat, float, ZeroSizedType>::type;
B b;
Run Code Online (Sandbox Code Playgroud)
除非我能告诉你C++中没有零大小的类型.唯一的例外似乎是"灵活阵列成员",所以我可以这样做:
using B = typename std::conditional<HasFloat, float, float[]>::type;
Run Code Online (Sandbox Code Playgroud)
除了它们仅在C99中支持,而不是C++.
对此的标准解决方案似乎是使用继承,因为基类可以是零大小的,但是我的结构也可以通过程序集访问,并且为了使程序集更简单,如果float b;它位于结构的末尾而不是开始,无论如何,这是不保证的.
所以这似乎是将模板专业化作为唯一的选择,但我的课实际上相当长,我想避免重复一切.我还缺少另一种解决方案吗?
我正在看这个答案,我想知道是否使用reinterpret_cast将对象转换为第一个成员并使用结果在C++中是安全的.
假设我们有一个A类,一个B类和一个B的实例b:
class A{
public:
int i;
void foo(){}
};
class B{
public:
A a;
};
B b;
Run Code Online (Sandbox Code Playgroud)
问题1:使用这样的ba是否安全:reinterpret_cast<A*>(&b)->foo()?
注意:在一般情况下,我们假设类及其成员都是标准布局.
我关于reinterpret_cast的可用引用的讲座告诉我这样的用法应该被授权,因为没有别名违规,但是它与许多答案冲突,比如这个.
问题2:使用这样的ba是否安全:static_cast<A*>(static_cast<void*>(&b))->foo()?
c++ type-conversion undefined-behavior reinterpret-cast c++11