检查向量是否在某个位置未初始化

时间:2019-04-04 14:00:22

标签: c++

这似乎是一件非常基本的事情,但是到目前为止我还是找不到解决方法,因为我总是只找到询问如何检查向量是否为空的问题,这就是不是我要检查的内容。
考虑下面的代码示例:

#include <iostream>
#include <vector>
using namespace std;

struct Atom {
    int x,y;
    int pol;
};

int main() {
    vector<vector<Atom>> vec=vector<vector<Atom>>(5,vector<Atom>(5));
    cout<<(vec[0][0]==nullptr); // this line doesn't compile, because the vector doesn't hold pointers.
    return 0;
}

我试图声明一个自定义类型的对象向量的向量。在程序的开头,我将初始化向量,使其具有特定的大小,但不为其分配实际对象。现在,我希望能够检查是否已将对象分配给矢量的特定位置。我本来想使用vec==nullptr之类的东西,但这是行不通的,因为向量中的对象不是指针。不幸的是,由于类是由ROS消息创建的,因此我不能仅仅更改structs标准的构造函数以放置一些指标值供我检查,例如Atom.pol==-2。关于如何检查是否已分配对象的其他建议?

编辑:分配对象后,pol始终为-1或1。那么检查Atom.pol==0是否安全?当我尝试在ideone.com上执行此操作时,它始终可以正常工作,但我认为不能保证将其设置为0,对吧?!

4 个答案:

答案 0 :(得分:4)

无法检查对象是否已初始化。就是说,std::vector的元素总是被初始化,因此也不需要进行任何检查。

似乎您想代表一个“未分配”的对象。标准库为您提供了一个模板:std::optional。如果创建矢量可选对象,则这些对象在初始化值时将处于“未分配”状态。

  

编辑:分配对象后,pol始终为-1或1。那么检查Atom.pol == 0是否安全?

是的,这很安全,因为您使用的构造函数会使用值初始化的参数来初始化元素。

如果您可以假定对象的某些状态为“无效”,则不必使用std::optional。如果值的初始化状态是这样的无效状态,则您也不需要向该类添加默认构造函数。就像值初始化指针的比较等于nullptr一样,初始化值Atom的整数成员也等于0。

  

但是我假设它不能保证为0,对吧?!

保证为0。

答案 1 :(得分:2)

使用pol == 0的解决方案应该没问题,只要pol == 0实际上不是该对象所处的正常状态,并且您不要在未初始化的实例中尝试它。 / p>

您正在使用std::vector constructor来保证新元素是default inserted。如果使用的是默认分配器,则执行这些新元素的value initialization。由于Atom是具有默认构造函数的类类型,该构造函数既不是用户提供的也不是用户删除的,则Atom的实例为zero initialized。这意味着Atom的每个成员值都初始化为零。

请注意,std::vector会这样做。您需要将Atom初始化为零,此方法才能起作用。如果尝试以下操作,则将是未定义的行为。 Atom成员未初始化,更不用说保证为零了:

int main()
{
    Atom a;
    std::cout << (a.pol == 0); // <- Not okay
}

您可以通过添加{}来强制值初始化:

int main()
{
    Atom a{};
    std::cout << (a.pol == 0); // <- Okay now
}

编辑:两个示例不小心使用了相同的代码示例。

答案 2 :(得分:1)

一种方法是将vec的签名更改为

vector<vector<Atom*>> vec=vector<vector<Atom*>>(5,vector<Atom*>(5));

然后,您可以执行null ptr检查以查看给定元素是否已初始化。但是,这确实增加了一些复杂性,因为您必须自己处理内存分配。

答案 3 :(得分:1)

如果要将Atom的成员初始化为特定值并检查它们是否已初始化,则可以执行此操作。

vector<vector<Atom>> vec=vector<vector<Atom>>(5,vector<Atom>(5, {1, 2, 3}));

这会将x, y, pol分别初始化为1, 23

最小示例:

int main() {

    using std::cout;
    using std::vector;

    vector<vector<Atom>> vec=vector<vector<Atom>>(5,vector<Atom>(5, {1, 2, 3}));
    cout<<((vec[0][0]).x == 1) << "\n"; 
    cout<<((vec[0][0]).y == 2)  << "\n";
    cout<<((vec[0][0]).pol == 3)  << "\n";

    cout<<((vec[0][0]).x == -1) << "\n"; 
    cout<<((vec[0][0]).y == -1)  << "\n";
    cout<<((vec[0][0]).pol == -1)  << "\n";

    return 0;
}

请参见 Demo