C++ 我可以安全地记忆一个非平凡的C++;具有用户定义构造函数的结构?

C++ 我可以安全地记忆一个非平凡的C++;具有用户定义构造函数的结构?,c++,C++,我知道可以安全地设置POD类。在c++17(?)中,std::is_pod被std::is_标准布局取代,std::is_琐碎如果一个非平凡但标准的布局结构只包含char[]数据和一个用户定义的构造函数,那么它是否可以安全地设置为memset。 具有数十个char[]成员变量的旧类 #include <cstring> #include <memory> #include <iostream> #include <type_traits> str

我知道可以安全地设置POD类。在c++17(?)中,std::is_pod被std::is_标准布局取代,std::is_琐碎如果一个非平凡但标准的布局结构只包含char[]数据和一个用户定义的构造函数,那么它是否可以安全地设置为memset。

具有数十个char[]成员变量的旧类

#include <cstring>
#include <memory>
#include <iostream>
#include <type_traits>

struct A
{
    // dozens of fields all char[] which need to initialized to '0'
    char foo[10]; // example char[] field
    // dozens of other fields all char[] which need to be initialized to non '0'

    struct AA
    {
        char bar[10];
        // dozens of other fields
    } sub[7];
};

// What I want to turn struct A into
struct B
{
    B()
    {
        // My question: Is this permissible?
        std::memset(this, '0', sizeof(*this));

        // Initialize all the other member variables that need different values
        std::memset(foo, ' ', sizeof(foo));
    }

    // dozens of fields all char[] which need to initialized to '0'
    char foo[10]; // example char[] field
    // dozens of other fields all char[] which need to be initialized to other values in constructor

    struct BB
    {
        char bar[10];
        // dozens of other fields
    } sub[7];
};

int main(int argc, char* argv[])
{
    bool isTrivialA = std::is_trivial<A>::value;
    bool isStandardLayoutA = std::is_standard_layout<A>::value;
    bool isTrivialCopyA = std::is_trivially_copyable<A>::value;

    std::cout << "Is A trivial: " << isTrivialA << std::endl;
    std::cout << "Is A standard layout: " << isStandardLayoutA << std::endl;;
    std::cout << "Is A trivial copy: " << isTrivialCopyA << std::endl << std::endl;

    bool isTrivialB = std::is_trivial<B>::value;
    bool isStandardLayoutB = std::is_standard_layout<B>::value;
    bool isTrivialCopyB = std::is_trivially_copyable<B>::value;

    std::cout << "Is B trivial: " << isTrivialB << std::endl;
    std::cout << "Is B standard layout: " << isStandardLayoutB << std::endl;
    std::cout << "Is B trivial copy: " << isTrivialCopyB << std::endl;
}
我想在更新的结构B上调用用户定义的构造函数,因为除了“0”之外,还有几十个字段实际上需要初始化为不同的值。我知道我可以用一个非成员函数来初始化这些值,但这看起来很笨拙

B newer; // Call user defined constructor

使用“this”指针的memset()在B中定义的构造函数是否安全/允许?

没有机制允许“memset”成为对象上的有效操作。这包括“吊舱”;标准中从来没有任何东西说直接将数据任意写入POD类型的对象表示中是可以的

简单的可复制性使得可以将对象表示复制到存储器中,并且可以将从该类型的有效实例获取的此类数据直接复制到该类型的另一个实例中。但是,即使是这样的指定,也无法将任意值直接设置到对象的表示中


实际上,只使用
()
{}
值初始化对象会更容易,这(如果它没有构造函数,因此符合旧的POD定义)将值初始化成员。

没有机制允许“memset”是对象上的有效操作。这包括“吊舱”;标准中从来没有任何东西说直接将数据任意写入POD类型的对象表示中是可以的

简单的可复制性使得可以将对象表示复制到存储器中,并且可以将从该类型的有效实例获取的此类数据直接复制到该类型的另一个实例中。但是,即使是这样的指定,也无法将任意值直接设置到对象的表示中


实际上,只使用
()
{}
值初始化对象会更容易,这(如果它没有构造函数,因此符合旧的POD定义)将值初始化成员。

不确定memset,但您可以很容易地在每个字段后添加
{}
初始值设定项,默认情况下将其置零。(嵌套结构中的字段甚至不需要这样做。)HolyBlackCat所说的对我有用,
char-foo[10]={}
sub[7]={}在结构声明中,现在所有感兴趣的内容都初始化为0。(不感兴趣的部分是如果有任何填充,这在
结构A
示例中不在我的平台上。)不确定memset,但您可以很容易地在每个字段后添加
{}
初始值设定项,默认情况下将其置零。(嵌套结构中的字段甚至不需要这样做。)HolyBlackCat所说的对我有用,
char-foo[10]={}
sub[7]={}在结构声明中,现在所有感兴趣的内容都初始化为0。(如果存在任何填充,则“不感兴趣”的部分将是,在
struct A
示例中,我的平台上没有填充。)
B newer; // Call user defined constructor