C++ 将向量中指向元素的指针设置为null,然后检查指针是否为null(C+;+;)

C++ 将向量中指向元素的指针设置为null,然后检查指针是否为null(C+;+;),c++,null,stdvector,C++,Null,Stdvector,我想将指向向量数组中某些元素的指针设置为NULL(基于条件),然后检查元素指针是否为NULL。如果指向该元素的指针为空,则从向量数组中删除该元素 我的编译器给了我一个错误,说地址表达式必须是左值或函数指示符,我不明白为什么(代码中注释了行位置)。由于我使用&获取值的地址,我是否没有看到指向该元素的指针是否为空 我包含了前面的代码,因为错误可能就在那里 相关代码: vector<particle> pl = c.particlelist; vector<particle>

我想将指向向量数组中某些元素的指针设置为NULL(基于条件),然后检查元素指针是否为NULL。如果指向该元素的指针为空,则从向量数组中删除该元素

我的编译器给了我一个错误,说地址表达式必须是左值或函数指示符,我不明白为什么(代码中注释了行位置)。由于我使用
&
获取值的地址,我是否没有看到指向该元素的指针是否为空

我包含了前面的代码,因为错误可能就在那里

相关代码:

vector<particle> pl = c.particlelist;
vector<particle> noncollision = c.particlelist;
vector<vector<particle>> collisionlist = new vector<vector<particle>>();
for (int i = 0; i < c.numparticles-1; i++){
    particle first = pl[i];
    for (int j = i+1; j < c.numparticles; j++)
    {
        particle second  = pl[j];
        double d = distance(first, second);
        if (d==0)
        {
            vector<particle> temp = {pl[i], pl[j]};
    collisionlist.push_back(temp);
            noncollision[i].setxposint(NULL); 
            noncollision[j].setxposint(NULL);
        }
        else
        {
        }
    }
}
int j = 0;
for (int i = 0; i < noncollision.size(); i++)
{
    if (&(noncollision[i].getxpos()) == NULL) ////// ERROR HERE
    {
        noncollision.erase(noncollision.begin()+i);
    }
    else
    {
        j++;
    }
}

noncollision[i].setxposint(NULL)

该行所做的就是将xpos设置为零。通常,术语
NULL
与指针一起使用,
0
与整数之类的东西一起使用
NULL
通常是
0L
的宏

&(非协作[i].getxpos())==NULL

这是不正确的,它试图从成员方法
getxpos()
获取返回值的地址,并将其与
NULL
进行比较。而你真正想做的只是看看函数是否返回零。因此,只需将这一行更改为:


noncollision[i].getxpos()==0
noncollision[i].setxposint(NULL)

该行所做的就是将xpos设置为零。通常,术语
NULL
与指针一起使用,
0
与整数之类的东西一起使用
NULL
通常是
0L
的宏

&(非协作[i].getxpos())==NULL

这是不正确的,它试图从成员方法
getxpos()
获取返回值的地址,并将其与
NULL
进行比较。而你真正想做的只是看看函数是否返回零。因此,只需将这一行更改为:


noncollision[i].getxpos()==0

似乎您正在尝试检查点对是否存在冲突。然后记录每个点是否有任何碰撞。这最好通过一个简单的标志列表来处理:

std::vector<bool> has_collision(c.numparticles, false); // init: no collisions found
最后,在标志列表上迭代并获得没有冲突的点:

for (size_t i = 0; i < c.numparticles; ++i)
{
    if (!has_collision[i])
    {
        // whatever
        // possibly push_back pl[i] into some list
    }
}
使用

向量冲突列表;

(或如上所述的向量)。

您似乎正在尝试检查点对是否存在碰撞。然后记录每个点是否有任何碰撞。这最好通过一个简单的标志列表来处理:

std::vector<bool> has_collision(c.numparticles, false); // init: no collisions found
最后,在标志列表上迭代并获得没有冲突的点:

for (size_t i = 0; i < c.numparticles; ++i)
{
    if (!has_collision[i])
    {
        // whatever
        // possibly push_back pl[i] into some list
    }
}
使用

向量冲突列表;

(或如上所述的
vector

您正在使用
&
获取指向临时值的指针(从
getxpos
返回的值),这是不允许的;由于临时地址将被删除,因此该地址在任何方面都不会有用,因此语言不允许使用它。即使你能得到它的地址,它也肯定不会是空的。

你正在使用
&
获取一个指向临时值的指针(从
getxpos
返回),这是不允许的;由于临时地址将被删除,因此该地址在任何方面都不会有用,因此语言不允许使用它。即使你能得到它的地址,它也肯定不会是空的。

在我看来,你试图跟踪“访问过的”项目,但不确定具体以哪种方式

您可以使用“外部”标记,而不是“修改”项目。这里有一套看起来不错。您可以在粒子列表中使用一组
迭代器,或者在本例中使用一组
索引(
i
j
),这可能会更稳定

这是一个开始:

#include <vector>
#include <set>

struct particle { };

double distance(particle const&, particle const&) { return 1.0; }

struct context
{
    std::size_t numparticles;
    std::vector<particle> particlelist;

    context() : numparticles(100), particlelist(numparticles) {}
};

static context c;

int main()
{
    using std::vector;
    using std::size_t;

    vector<particle> pl = c.particlelist;
    vector<vector<particle>> collisionlist;

    std::set<size_t> collision;

    for(size_t i = 0; i < c.numparticles-1; i++)
    {
        particle first = pl[i];
        for(size_t j = i+1; j < c.numparticles; j++)
        {
            particle second  = pl[j];
            double d = distance(first, second);
            if(d < 0.0001)
            {
                collisionlist.push_back({pl[i], pl[j]});
                collision.insert(i);
                collision.insert(j);
            }
            else
            {
            }
        }
    }

    for(size_t i = 0; i < pl.size(); i++)
    {
        if(collision.end() != collision.find(i))
        {
            // do something
        }
    }

    // alternatively
    for (int index : collision)
    {
        particle& p = pl[index];
        // do something
    }
}
因为它可能不会达到你的预期


在我看来,您试图跟踪“访问”的项目,但不确定具体以哪种方式进行

您可以使用“外部”标记,而不是“修改”项目。这里有一套看起来不错。您可以在粒子列表中使用一组
迭代器,或者在本例中使用一组
索引(
i
j
),这可能会更稳定

这是一个开始:

#include <vector>
#include <set>

struct particle { };

double distance(particle const&, particle const&) { return 1.0; }

struct context
{
    std::size_t numparticles;
    std::vector<particle> particlelist;

    context() : numparticles(100), particlelist(numparticles) {}
};

static context c;

int main()
{
    using std::vector;
    using std::size_t;

    vector<particle> pl = c.particlelist;
    vector<vector<particle>> collisionlist;

    std::set<size_t> collision;

    for(size_t i = 0; i < c.numparticles-1; i++)
    {
        particle first = pl[i];
        for(size_t j = i+1; j < c.numparticles; j++)
        {
            particle second  = pl[j];
            double d = distance(first, second);
            if(d < 0.0001)
            {
                collisionlist.push_back({pl[i], pl[j]});
                collision.insert(i);
                collision.insert(j);
            }
            else
            {
            }
        }
    }

    for(size_t i = 0; i < pl.size(); i++)
    {
        if(collision.end() != collision.find(i))
        {
            // do something
        }
    }

    // alternatively
    for (int index : collision)
    {
        particle& p = pl[index];
        // do something
    }
}
因为它可能不会达到你的预期


    • 我将解释为什么编译器不理解您的意思

      当你写作时

      &(someFunction())
      
      您正在询问函数返回的对象的地址。但是函数返回值。值没有地址。变量有地址

      当某物是一个记忆单词(将包含一个值)时,它可以用作左值(left value),因为你可以将东西放入该记忆单词中:

      int b = 1; //make room for an `int` on the stack, then put a `1` there.
      
      当某物只是一个值时,它只能用作右值。以下内容无法编译,原因与您的代码无法编译的原因相同:

      int b; //make room for an `int` on the stack.
      42 = b; //ERROR, this makes no sense.
      if (42 == NULL) { std::cout << "this is never true" << std::endl; }
      &42; //ERROR, 42 isn't a piece of memory, it's a value.
      

      意思是“将
      b
      的值放入地址为
      42
      的内存中。这可以很好地编译(但如果不允许在42写入内存,则会崩溃)。

      我将解释为什么编译器不理解您的意思

      当你写作时

      &(someFunction())
      
      您正在询问函数返回的对象的地址。但是函数返回值。值没有地址。变量有地址

      当某物是一个记忆单词(将包含一个值)时,它可以用作左值(left value),因为你可以将东西放入该记忆单词中:

      int b = 1; //make room for an `int` on the stack, then put a `1` there.
      
      当某个内容只是一个值时,它只能用作右值。以下内容无法编译,原因与您的代码无法编译的原因相同:

      int b; //make room for an `int` on the stack.
      42 = b; //ERROR, this makes no sense.
      if (42 == NULL) { std::cout << "this is never true" << std::endl; }
      &42; //ERROR, 42 isn't a piece of memory, it's a value.
      
      意思是“将
      b
      的值放入地址为
      42
      的内存中。这很好