c++ - 结构根据空基类顺序更改大小

标签 c++ c++17 multiple-inheritance sizeof crtp

我正在编写一个用于练习的数学 vector 和矩阵库,并且我使用了一个 crtp 基类,以便不必多次定义多个函数。我还继承了一个静态数组类。但是,根据继承类的顺序,我在 msvc 中的结构得到了不同的大小。这是一个错误,还是我应该预料到的?您可以在以下位置找到现场演示:https://godbolt.org/z/3EPVI5 请注意,在 gcc 中同样可以正常编译。 引用代码:

template<typename D>
struct crtp
{

};

template<typename T, int s>
struct arr_impl
{
    T e[s];
};

template<typename T, int s>
struct vc : public arr_impl<T, s>, public crtp<vc<T, s>>
{

};

template<typename T, int s>
struct vc2 : public crtp<vc2<T, s>>, public arr_impl<T, s>
{

};

int main()
{
    static_assert(sizeof(vc<vc<float,3>,2>) == 24);
    static_assert(sizeof(vc2<vc2<float,3>,2>) == 24);
    return 0;
}

我进一步缩小了范围,请参阅:https://godbolt.org/z/tGCn_J 因为看起来只需要嵌套和一个空类:

struct empty_struct{};

template<typename T>
struct st
{
    T a;
};

template<typename T>
struct vc : public empty_struct, public st<T> {};

template<typename T>
struct vc2 : public st<T>, public empty_struct{};

int main()
{
    static_assert(sizeof(vc<vc<float>>) == 4);
    static_assert(sizeof(vc2<vc2<float>>) == 4);
    return 0;
}

最佳答案

我相信 MSVC 在这方面符合 C++17 标准。

来自 [intro.object] (强调我的):

Unless it is a bit-field, a most derived object shall have a nonzero size and shall occupy one or more bytes of storage. Base class subobjects may have zero size. An object of trivially copyable or standard-layout type shall occupy contiguous bytes of storage.

这就是 C++17 标准在这个问题上的全部内容。空基优化是完全可选的。标准只是说它是合法的,并不是说必须执行,或者在什么情况下应该执行。


C++20 标准的当前草案更具规范性。

来自 [intro.object] (再次强调我的)

An object has nonzero size if it
-- is not a potentially-overlapping subobject, or
-- is not of class type, or
-- is of a class type with virtual member functions or virtual base classes, or
-- has subobjects of nonzero size or bit-fields of nonzero length.
Otherwise, if the object is a base class subobject of a standard-layout class type with no non-static data members, it has zero size. Otherwise, the circumstances under which the object has zero size are implementation-defined. Unless it is a bit-field, an object with nonzero size shall occupy one or more bytes of storage, including every byte that is occupied in full or in part by any of its subobjects. An object of trivially copyable or standard-layout type ([basic.types]) shall occupy contiguous bytes of storage.

因此在 C++20 下,您的基类将保证具有零大小,因为它是标准布局类的空基类。

关于c++ - 结构根据空基类顺序更改大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57128986/

相关文章:

c++ - 带文字列表的范围 for 循环?

c++ - 如何使用 C++14 和 C++1z 中的功能缩短此可变参数模板代码?

c++ - 与 std::list 一起使用的指针上的接口(interface)类型转换的多重继承

c++ - regex_match 和 regex_search 之间的区别?

c++ - boost Kamada-Kawai spring 布局顶点碰撞

c++ - 要求通过 static_cast<double>(x) 显式调用运算符 double()

c++ - 将包含重音字符的 UTF-8 字符串转换为 UTF-16

python - python的多重继承

c++ - 我如何访问继承代码的不同部分

c++ - 需要有关二维数组的建议