【问题标题】:how to check std::array is declared but not explicitly initialized如何检查 std::array 已声明但未显式初始化
【发布时间】:2021-03-20 06:20:09
【问题描述】:

std::array 有一个内置方法empty() 来检查数组是否为空。如从here复制的示例:

#include <array>
#include <iostream>
 
int main()
{
    std::array<int, 4> numbers {3, 1, 4, 1};
    std::array<int, 0> no_numbers;
 
    std::cout << std::boolalpha;
    std::cout << "numbers.empty(): " << numbers.empty() << '\n';
    std::cout << "no_numbers.empty(): " << no_numbers.empty() << '\n';
}

有什么方法可以检查数组是否已声明,大小固定,但未显式初始化?

说,像这样?

std::array<int,4> a;
std::array<int,4> b;
a = {1,2,3,4}; //a holds some explicit values
//do not assign values to b
//how to tell the different state of a and b?

【问题讨论】:

  • 没有。读取一个未初始化的变量就是UB,在实践中往往会导致得到垃圾值,无法与初始化数组的内容区分开来。
  • 为了使这个功能存在,需要单独跟踪数组的状态(已初始化或未初始化)。但是std::array 与 C 数组相比没有内存开销,因此它无法支持。您可以尝试std::optional&lt;std::array&lt;int, 4&gt;&gt; 向您的数组添加某种定义明确的“未指定”状态。
  • 即使使用常规数组,您也无法判断常规数组是否已初始化。垃圾 01(或任何您的初始值)就像使用 01 初始化数组一样。

标签: c++ arrays stl


【解决方案1】:

没有。 std::array&lt;T, N&gt;::empty() 其中 N!=0 将始终返回 falsehttps://en.cppreference.com/w/cpp/container/array/empty "检查容器是否没有元素,即是否 begin() == end()。"

同样std::array&lt;T, 0&gt;::empty() 将始终返回true,因为begin() == end()

【讨论】:

    【解决方案2】:

    std::array 对象的大小(即它拥有的元素数量)必须是一个编译时常量,并且不能动态更改。因此,empty()size() 成员函数可能看起来有些多余(但出于与 STL 提供的通用、基于容器的算法兼容的原因而包含在内)。

    如果您需要一个大小可以更改的容器,那么您应该使用std::vector 而不是std::array(尽管这会产生更多的运行时开销)。

    以下说明了其中一种差异:

    #include <iostream>
    #include <array>
    #include <vector>
    
    int main()
    {
        std::array<int, 4> a;
        std::array<int, 4> b;
        a = { 1,2,3,4 }; //a holds some explicit values
    
        std::cout << std::boolalpha;
        std::cout << "a.empty(): " << a.empty() << '\n'; // false
        std::cout << "b.empty(): " << b.empty() << '\n'; // false
    
        // However ...
        std::vector<int> v1;
        std::vector<int> v2;
        v1 = { 1,2,3,4 };
        std::cout << "v1.empty(): " << v1.empty() << '\n'; // false
        std::cout << "v2.empty(): " << v2.empty() << '\n'; // true
    
        return 0;
    }
    

    但请注意,这些成员 对于将数组传递给函数的情况很有用,否则将无法确定大小(或空)其给定参数。

    【讨论】:

    • 或者,可能是因为与 STL 提供的其他容器类型“兼容”而包含在内” - 不是为了与其他容器兼容 ,但为了与以通用方式对多种容器类型进行操作的标准算法兼容。因此,这些容器需要有一个一致的接口。算法不关心容器的实现,只关心接口的结果。
    • @RemyLebeau 感谢您的更正/澄清。我实际上对我原来的措辞有点不舒服(见编辑)。
    【解决方案3】:

    我不明白你在问什么:

    有什么方法可以检查数组是否已声明,大小固定,但未显式初始化?

    如果你有一个std::array 类型的变量,那么它已经被构造了。 如果它已被构造,则数组中的元素已被构造。 (这是在 array 构造函数中完成的)

    此变量std::array&lt;std::string, 5&gt; sa; 包含 5 个默认构造的字符串。

    所以我不知道你所说的“已声明,但未显式初始化”是什么意思

    【讨论】:

    • 来自 cppreference:请注意,默认初始化可能会导致非 T 类的值不确定。 (并不是我说你是 - 只是澄清默认初始化并不总是与显式初始化相同。)
    • 我的意思是在std::array&lt;int, 2&gt; a={1,2} 中,a 被赋予了值,但在std::array&lt;int,2&gt; b 中,b 没有明确的值。如何区分a和b的状态?
    • "如何区分a和b的状态?"嗯,比较一下?这会告诉你它们是否不同。但我认为这不是你要问的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 2012-02-10
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多