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

C++ 检查向量是否在某个位置未初始化,c++,C++,这似乎是一件非常基本的事情,但无论如何,到目前为止,我无法找到解决方案,因为我总是只找到一些问题,这些问题是关于如何检查向量是否为空的,这不是我想要检查的。 考虑这个代码示例: #include <iostream> #include <vector> using namespace std; struct Atom { int x,y; int pol; }; int main() { vector<vector<Atom>

这似乎是一件非常基本的事情,但无论如何,到目前为止,我无法找到解决方案,因为我总是只找到一些问题,这些问题是关于如何检查向量是否为空的,这不是我想要检查的。 考虑这个代码示例:

#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之类的东西,但这不起作用,因为向量中的对象不是指针。不幸的是,我不能仅仅更改structs标准构造函数来放置一些可以检查的指示符值,比如Atom.pol=-2,因为类是由ROS消息创建的。关于如何检查我是否已经分配了对象,还有其他建议吗


编辑:指定对象后,pol将始终为-1或1。那么检查Atom.pol==0安全吗?当我在ideone.com上尝试这样做时,它总是有效的,但我假设它不能保证为0,对吗

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

向量向量=向量5,向量5


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

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

向量向量=向量5,向量5


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

无法检查对象是否已初始化。也就是说,std::vector的元素总是初始化的,所以也不需要检查

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

编辑:指定对象后,pol将始终为-1或1。那么检查Atom.pol==0安全吗

是的,这是安全的,因为您使用的构造函数使用值初始化参数初始化elments

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

但我假设它不一定是0,对吧


它保证为0。

无法检查对象是否已初始化。也就是说,std::vector的元素总是初始化的,所以也不需要检查

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

编辑:指定对象后,pol将始终为-1或1。那么检查Atom.pol==0安全吗

是的,这是安全的,因为您使用的构造函数使用值初始化参数初始化elments

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

但我假设它不一定是0,对吧


它保证为0。

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

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

请参见

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

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

使用pol==0的解决方案应该是好的,前提是pol==0实际上不是该对象所处的正常状态,并且您不使用未初始化的实例进行尝试

您正在使用的std::vector保证新元素是正确的。如果您使用的是默认分配器,那么它将执行这些新元素的分配。由于Atom是一个具有默认构造函数的类类型,该构造函数既不是用户提供的,也不是删除的,所以您的Atom实例是。这意味着每个Atom成员的值都被初始化为零

请注意,这是std::vector所做的事情。你需要初始化你的原子 此方法的有效性为零。如果您尝试以下操作,则这将是未定义的行为。原子成员未初始化,更不用说保证为零:

int main()
{
    Atom a;
    std::cout << (a.pol == 0); // <- Not okay
}
编辑:意外地对两个示例使用了相同的代码示例。

使用pol==0的解决方案应该可以,前提是pol==0实际上不是该对象所处的正常状态,并且您没有使用未初始化的实例进行尝试

您正在使用的std::vector保证新元素是正确的。如果您使用的是默认分配器,那么它将执行这些新元素的分配。由于Atom是一个具有默认构造函数的类类型,该构造函数既不是用户提供的,也不是删除的,所以您的Atom实例是。这意味着每个Atom成员的值都被初始化为零

请注意,这是std::vector所做的事情。你需要将你的原子初始化为零,这种方法才能工作。如果您尝试以下操作,则这将是未定义的行为。原子成员未初始化,更不用说保证为零:

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

编辑:意外地对两个示例使用了相同的代码示例。

在您的用例中,检查Atom.pol==0是完全安全的,但我宁愿将pol声明为未知值等于0的枚举类类型。@nutchracker是吗?那在什么情况下不安全呢?因为这显然不是我的实际代码,只是一些小东西来演示我的issue@NutCracker你最好改掉全大写的坏习惯CONSTANTS@Max如果0是一个可能的值,那么它就不安全了。在您的情况下,0是非法值,现在绝对有办法检查某些内容是否已初始化。程序员有责任确保程序从不尝试访问未初始化的值。因此,为了使事情显式化,您可以在用例中为Atom添加默认构造函数,检查Atom.pol==0是完全安全的,但我宁愿将pol声明为未知值等于0的枚举类类型。@nutchracker它是吗?那在什么情况下不安全呢?因为这显然不是我的实际代码,只是一些小东西来演示我的issue@NutCracker你最好改掉全大写的坏习惯CONSTANTS@Max如果0是一个可能的值,那么它就不安全了。在您的情况下,0是非法值,现在绝对有办法检查某些内容是否已初始化。程序员有责任确保程序从不尝试访问未初始化的值。因此,为了使事情明确化,您可以为Atom添加默认构造函数。在这种情况下,最好使用std::unique_ptr而不是原始指针。在这种情况下,最好使用std::unique_ptr而不是原始指针。std::optional可从C++17上获得。对于该语言的早期版本,OP应该求助于boost::optional。std::optional可从上的C++17获得。对于该语言的早期版本,OP应该求助于boost::optional。