c++ - 作为类成员的 `std::array<int, N>`中的元素是否默认初始化

标签 c++ constructor initialization stdarray std-variant

考虑:

class x {
    std::array<int, 4> data_;

public:
    x() /*no reference to data_ here*/ {}
};
int中的data_元素是否置零,或者它们的值不确定?

通过扩展,在这种情况下也是如此:
class x {
    std::variant<std::array<int, 4> /*other stuff here*/> data_;

public:
    x() /*no reference to data here*/ {
        data_.emplace<std::array<int, 4>>(/* no args */);
    }
};

编辑:

扩展:有没有一种方法可以使我从变体中获得所需的行为(不初始化数据)。

如果将两个示例结合在一起,我应该可以:
struct no_init_array {
     std::array<int, 4> array;
     no_init_array() { } //does nothing
};

class x {
    std::variant<no_init_array/*other stuff here*/> data_;

public:
    x() /*no reference to data here*/ {
        //call default ctor of no_init_array
        //which does not init the std::array (I hope)
        data_.emplace<no_init_array>(/* no args */);
    }
};

最佳答案

std::array documentation,在构造函数的部分中,我们可以读取:

initializes the array following the rules of aggregate initialization (note that default initialization may result in indeterminate values for non-class T)



重点矿

就您而言,您有一个std::array<int, 4>int匹配非类类型的定义,因此默认初始化将使data_成员内容具有不确定的值。

如果您将data_成员初始化为:
std::array<int, 4> data_ {}; // Note the braces

元素将被值初始化,这将导致int元素为零初始化。

编辑(来自评论):

std::variant::emplace() 转发其参数,但是由于您没有为放置的std::array<int, 4>提供任何参数,因此您的std::variant将保存一个值初始化的std::array<int, 4>,因此基础int元素将被零初始化。

由于您需要第二个用例,并且希望数组内容保持未初始化,因此您当然可以执行建议的操作:
struct X
{
    std::array<int, 4> data_;

    X()
    {}
};
struct Y
{
    std::variant<X, /*...*/> data_ {};

    Y()
    {
        data_.emplace<X>();
    }
};

Live example

但是您需要注意,在以后对其进行正确初始化之前,不会意外访问数组的内容。

编辑:

之后要初始化std::array,您应确保它是通过引用而不是数组的副本执行的(为了避免通过复制未初始化的数据来产生未定义的行为)。

例如:
Y y;

//X x = std::get<X>(y); // Wrong
X & x = std::get<X>(y); // Right

x.data_[0] = 42;
x.data_[1] = 422;
x.data_[2] = 442;
x.data_[3] = 4422;

关于c++ - 作为类成员的 `std::array<int, N>`中的元素是否默认初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60414176/

相关文章:

c++ - gdb 显示类成员的乱码值,尽管代码有效

c++ - 初始化列表与 vector

c++ - 使用 friend 访问模板类中的私有(private)变量

javascript - fabric.Canvas 不是构造函数

c++ - C++ 构造函数定义中冒号后面的这个奇怪的东西是什么?

.net - 是否可以使用属性初始化 .NET 类型?

java - CMake 构建在 Android Studio 中似乎不并行

c++ - 将所有工作汇总到一个循环中还是将其分成多个循环更好?

java - 为什么此构造函数中不需要 "this."命令? ( java )

c++ - g++ 4.8.2 在列表方法参数默认初始化时出错