Question

I have a class Node and a derived class ChildNode as given below

#include<iostream>
using namespace std;
class Node
{
public:
    int nodeId;
    bool operator==(int id) const { return (this->nodeId ==id);}; //used in STL Find function
    Node(int id)
    {
        this->nodeId=id;
    }
    ~Node(void)
    {
    }
    virtual void SaySomeThing()
    {
        cout<<"Hey! I am node"<<endl;
    }
};
class ChildNode:public Node
{
public:
    ChildNode(int id):Node(id){};
    virtual void SaySomeThing()
    {
        cout<<"Hey! I am a child node"<<endl;
    }
};

Now in main I call NodeVectorTest method having vector object which contains nodes

void NodeVectorTest()
{
    vector<Node> nodes;
    Node *node=new Node(22);
    nodes.push_back(*node);
    delete node;
    node=new ChildNode(23);
    nodes.push_back(*node);
    delete node;
    node=new Node(33);
    nodes.push_back(*node);
    delete node;

    //Find node
    vector<Node>::iterator nodePosition;
    int nodeId=23;
    nodePosition =find(nodes.begin(),nodes.end(),nodeId);
    if(nodePosition == nodes.end()) { ///we didnt find the node id ..

        cerr<<"node id "<< nodeId <<" Could not be found "<<endl;

        return ;
    }

    else{ //now we have the right node to do our desired stuff
        (*nodePosition).SaySomeThing();
    }
}

when I found node 23 it is converted into Node object instead of Node*, so that it is showing output as Hey! I am node to achieve polymorphism, I converted this vector<Node> nodes; to vector<Node*> nodes; as code given below

vector<Node*> nodes;
Node *node=new Node(22);
nodes.push_back(node);
node=new ChildNode(23);
nodes.push_back(node);
node=new Node(33);
nodes.push_back(node);

//Find node
vector<Node*>::iterator nodePosition;
int nodeId=23;
nodePosition =find(nodes.begin(),nodes.end(),nodeId);

if(nodePosition == nodes.end()) { ///we didnt find the node id ..

    cerr<<"node id "<< nodeId <<" Could not be found "<<endl;

    return ;
}

else{ //now we have the right node to do our desired stuff
    (*nodePosition).SaySomeThing();
}

When I change it into this I got the following error

Error 1 error C2446: '==' : no conversion from 'const int' to 'Node *' microsoft visual studio 11.0\vc\include\xutility
Error 2 error C2040: '==' : 'Node *' differs in levels of indirection from 'const int' microsoft visual studio 11.0\vc\include\xutility

Any help in this regard ?

Was it helpful?

Solution

The elements of nodes is the pointer to Node, not Node. So, you should use std::find_if.

nodePosition = find_if(nodes.begin(), nodes.end(),
    [nodeId](Node *p) { return *p == nodeId; });

PS. Although c++11 is the tag of your question, you didn't use any nice features of C++11!

PS2. Notice your first example with vector<Node> will occur slicing problem.

PS3. And in your first example, you need not and should not use new. just nodes.push_back(Node(22)); or nodes.emplace_back(22);.

OTHER TIPS

Please note that by default find will use an operator== that compares an object to another object of the same type. In this case you need to overload bool operator==(const Node*, const Node*) which is not possible. A far better option for you is to use find with predicate, which is implemented in the function std::find_if.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top