【问题标题】:remove_if not working, not sure what the issue isremove_if 不工作,不确定是什么问题
【发布时间】:2014-05-30 10:19:09
【问题描述】:

我正在从向量中删除元素,但我的 remove_if 语句似乎无法正常工作。我有一个用我的结构填充的向量,当我循环遍历向量时,我删除了任何符合条件的元素。

我的矢量:

vector<vertex*> nodes { &s, &A, &G, &D, &B, &H, &E, &C, &I, &F, &t };

和 remove_if 语句:

nodes.erase(remove_if(nodes.begin(), nodes.end(), shouldDelete(i)),
                nodes.end());

这是决定我是否应该删除:

bool shouldDelete(vertex i) {
return (i.incomingEdges == 0);
}

通常我可以解决问题,但是我遇到的错误非常奇怪:

构建文件:../src/Main.cpp 调用:GCC C++ 编译器 g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++0x -MMD -MP -MF"src/Main.d" -MT"src/Main.d" -o

/Library/Developer/CommandLineTools/usr/bin/../lib/c++/v1/algorithm:2117:18:错误:调用的对象类型“int”不是函数或函数指针

        if (!__pred(*__i))
             ^~~~~~

../src/Main.cpp:95:16:注意:在此处请求的函数模板特化 'std::__1::remove_if, bool>' 的实例化 节点.erase(remove_if(nodes.begin(), nodes.end(), shouldDelete(i)), ^

/Library/Developer/CommandLineTools/usr/bin/../lib/c++/v1/algorithm:859:13:错误:调用的对象类型'int'不是函数或函数指针

    if (__pred(*__first))
        ^~~~~~

/Library/Developer/CommandLineTools/usr/bin/../lib/c++/v1/algorithm:2110:22: 注意:在函数模板特化'std::__1::find_if, bool &>'的实例化中在这里请求 __first = _VSTD::find_if<_forwarditerator typename add_lvalue_reference>::type> ^

../src/Main.cpp:95:16:注意:在此处请求的函数模板特化 'std::__1::remove_if, bool>' 的实例化 nodes.erase(remove_if(nodes.begin(), nodes.end(), shouldDelete(i))

以下是其余代码,见长见谅:

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <iterator>

using namespace std;

struct vertex {
char vertexName;
int incomingEdges;
vertex* nextDoorTop = nullptr;
vertex* nextDoorMiddle = nullptr;
vertex* nextDoorBottom = nullptr;
bool markToDelete = false;
};
void queueNodes(vector<vertex*>& nodes, queue<vertex*>& q);
bool shouldDelete(vertex i);

int main() {
vertex s, A, G, D, B, H, E, C, I, F, t;
s.vertexName = 's';
s.incomingEdges = 0;
s.nextDoorTop = &A;
s.nextDoorMiddle = &D;
s.nextDoorBottom = &G;
A.vertexName = 'A';
A.incomingEdges = 2;
A.nextDoorTop = &B;
A.nextDoorMiddle = &E;
G.vertexName = 'G';
G.incomingEdges = 1;
G.nextDoorTop = &D;
G.nextDoorMiddle = &E;
G.nextDoorBottom = &H;
D.vertexName = 'D';
D.incomingEdges = 2;
D.nextDoorMiddle = &E;
B.vertexName = 'B';
B.incomingEdges = 1;
B.nextDoorTop = &C;
H.vertexName = 'H';
H.incomingEdges = 1;
H.nextDoorTop = &E;
H.nextDoorMiddle = &I;
E.vertexName = 'E';
E.incomingEdges = 4;
E.nextDoorTop = &C;
E.nextDoorMiddle = &F;
E.nextDoorBottom = &I;
C.vertexName = 'C';
C.incomingEdges = 3;
C.nextDoorMiddle = &t;
I.vertexName = 'I';
I.incomingEdges = 2;
I.nextDoorTop = &F;
I.nextDoorMiddle = &t;
F.vertexName = 'F';
F.incomingEdges = 2;
F.nextDoorMiddle = &t;
t.vertexName = 't';
t.incomingEdges = 3;

vector<vertex*> nodes { &s, &A, &G, &D, &B, &H, &E, &C, &I, &F, &t };
queue<vertex*> q;
cout << "Vertex Name: " << " Number Of Edges: " << endl;
for (const auto& n : nodes) {
    const auto& i = *n;
    cout << i.vertexName << "         " << i.incomingEdges
            << "                 " << endl;
}
int counter = 0;
while (counter < 5) {
    queueNodes(nodes, q);
    counter++;
}
return 0;
}
bool shouldDelete(vertex i) {
return (i.incomingEdges == 0);
}
void queueNodes(vector<vertex*>& nodes, queue<vertex*>& q) {
for (auto n : nodes) {
    auto& i = *n;
    cout << endl << i.vertexName << "             " << i.incomingEdges;
    if (i.incomingEdges == 0) {
        if (i.nextDoorTop)
            i.nextDoorTop->incomingEdges--;
        if (i.nextDoorMiddle)
            i.nextDoorMiddle->incomingEdges--;
        if (i.nextDoorBottom)
            i.nextDoorBottom->incomingEdges--;
        cout << " foo";
        q.push(&i);
        nodes.erase(remove_if(nodes.begin(), nodes.end(), shouldDelete(i)),
                nodes.end());
    } else {
        cout << " bar";
    }
    cout << "Queue Size: " << q.size();
}
}

【问题讨论】:

    标签: algorithm c++11 vector


    【解决方案1】:

    将你的 shouldDelete 函数更改为:

    bool shouldDelete(const vertex *i) {
        return (i == nullptr || i->incomingEdges == 0);
    }
    

    然后这样调用函数:

    nodes.erase(remove_if(nodes.begin(), nodes.end(), shouldDelete), nodes.end());
    

    【讨论】:

    • 为什么需要 i==nullptr 检查?
    • 确保不取消引用空指针。 OP 可以决定将其删除,但为了安全起见,进行该检查可能是明智的。他还可以将其更改为i != nullptr,这只会删除长度为 0 的传入边
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 2020-12-01
    • 2021-01-12
    • 1970-01-01
    相关资源
    最近更新 更多