Reputation: 4414
I have a set of pointers:
set<StudentInterface*, Comparator> studentSet;
These pointers point to Student
classes which inherit from StudentInterface
and contain an int value ID
. I want to test if a certain class has a particular value for ID. My current idea for doing so is as follows:
if(studentSet.find(????->getID()) != studentSet.end()) /* do something */
Is there a way to access the data elements this way? If not, what is the shortest way (in lines of code) that I can access these elements to test them?
Upvotes: 0
Views: 92
Reputation: 1536
I think there is in my opinion a more elegant solution by using a comparator function.
Given you have the class Student defined as
class Student {
public:
Student(int id) : id(id) { }
Student(int id, std::string name) : id(id), name(name) { }
int id;
std::string name;
};
then you can define a comparator function when creating the set, which is then used in find. In this case this function has the signature bool (Student, Student)
.
int main() {
std::set<Student, std::function<bool (Student, Student)>> data(
[](Student a, Student b) {
return a.id < b.id;
});
data.insert(Student(1, "foo"));
data.insert(Student(2, "bar"));
data.insert(Student(3, "foobar"));
std::set<Student>::iterator it = data.find(Student(2));
std::cout << "Element found with id " << it->id << " and name " << it->name << std::endl;
return 0;
}
The output in this cas would be
Element found with id 2 and name bar
EDIT: Additionally you can check if an element was found by
if (it != data.end()){
// found
} else {
// not found
}
Upvotes: 0
Reputation: 33931
Ran out of time. No point to using a set and then searching the set manually. Might as well use a vector. Here is the framework of a better way:
#include <iostream>
#include <set>
using namespace std;
class Interface
{
public:
Interface(int ID):mID(ID)
{
}
bool operator<(const Interface& rhs)
{
return mID < rhs.mID;
}
int mID;
};
class InterfaceTest:public Interface
{
public:
InterfaceTest(int ID): Interface(ID)
{
}
};
class InterfaceKey:public Interface
{
public:
InterfaceKey(int ID): Interface(ID)
{
}
};
struct compare {
bool operator() ( Interface* const& lhs, Interface* const& rhs) const{
return *lhs < *rhs;
}
};
int main()
{
set<Interface*, compare> testset;
testset.insert(new InterfaceTest(1));
testset.insert(new InterfaceTest(2));
testset.insert(new InterfaceTest(3));
testset.insert(new InterfaceTest(4));
InterfaceKey A(1);
if (testset.find(&A) != testset.end())
{
cout << "Found A" << endl;
}
InterfaceKey B(5);
if (testset.find(&B) == testset.end())
{
cout << "Did not find B" << endl;
}
}
Upvotes: 0
Reputation: 853
You can also use set
's iterator which comes included with the libraries. For example, given the set studentSet
, you can:
for (std::set<StudentInterface*, Comparator>::iterator it=studentSet.begin(); it!=studentSet.end(); ++it){
//Code here, example:
*it->getID();
}
This for
will iterate from the first element of studentSet
until the last element, with it
receiving the object stored. Also, it
will be receiving a reference(pointer) to the element.
Upvotes: 0
Reputation: 354
I don't think you can search for a particular element value of a class using find function from any STL container like vector/set/map.
You can do this in following manner :
for ( auto x : studentSet )
{
if ( x->getID() == ???? )
{
/* Do something */
}
}
Or if you can make a object to search, then you can do same thing as you asked in question :
if ( studentSet.find(studentSet.begin(), studentSet.end(), YourObject) != studentSet.end() )
/* do something */
Upvotes: 1
Reputation: 4414
Okay I have a tentative answer to this question. I can use the following to search the set for the desired element:
for(StudentInterface* currentSetElement : studentSet) if(currentSetElement->getID() == ID) /* do something */
Not sure if that's the best way but I think it works.
Upvotes: 0