I have a struct like this:
struct group
{
int index;
string name;
group* child;
};
And I set up a vector to store some group structs.
Now I am trying to have a function to retrieve a group member from that vector by index, something like this:
148 newGroup.child = getGroupByIndex(world, i);
And the definition of the function is :
group& getGroupByIndex(vector<group>* world, int i)
{
for(vector<group>::iterator it = world->begin();
it < world->end(); ++it)
{
if(it->index == i) return *it;
}
267 return 0;
}
Unfortunately, it won't even compile.
And the error message is :
tree.cpp: In function ‘int main()’:
tree.cpp:148: error: cannot convert ‘group’ to ‘group*’ in assignment
tree.cpp: In function ‘group& getGroupByIndex(std::vector<group, std::allocator<group> >*, int)’:
tree.cpp:267: error: invalid initialization of non-const reference of type ‘group&’ from a temporary of type ‘int’
My two problems,
how to fix the compile error? what return type should I use?
If I want to return a null pointer in line 267, what should I use? I tried (void *)0 and 0, but neither works.
I think it should be like this:
group* getGroupByIndex(vector<group*> world, int i) // See position of two *
{
for(vector<group*>::iterator it = world.begin();
it < world.end(); ++it)
{
if(it->index == i)
return *it;
}
return 0;
}
or
group* getGroupByIndex(vector<group> *world, int i) // See position of two *
{
for(vector<group>::iterator it = world->begin();
it < world->end(); ++it)
{
if(it->index == i)
return &(*it);
}
return 0;
}
If you want prefer references to pointers, you can also define a "not found" group object that will be returned by your function.
I would do that like this :
struct group
{
int index;
string name;
group* child;
group(int i):index(i),child(null){}
group(int i, const string& n, group& c):index(i), name(n), child(&c){}
// assuming index defines the uniqueness of your object class
bool operator == (const struct group& g)const {return (index == g.index);}
// an unique special instance of group struct
static struct group not_found;
};
group group::not_found(-1);
thus you can define your function the way you wanted :
group& getGroupByIndex(vector<group>* world, int i)
{
for(vector<group>::iterator it = world->begin();
it < world->end(); ++it)
{
if(it->index == i) return *it;
}
return group::not_found; // a reference to a special singleton instance of struct group
}
and you will be able to make calls like this :
...
group& g = getGroupByIndex(world, index);
if(g == group::not_found)
{
// handle the not found case here
...
boost::optional
boost::optional<group&> get(vector<group>& world, int i)
{
for(auto & grp : world)
{
if(grp.index == i)
return boost::optional<group&>(grp);
}
return boost::none;
}
Please note that this solution has O(n)
complexity. If you want to search basing on index
, I'd recommend using a structure that has references to group
objects sorted by index
, which would give you O(log n)
lookup time.
In that case, I'd probably hold a vector of shared_ptr
s and a map<int, weak_ptr>
. You could also take a look at boost::multi_index
Ah, and just a sidenote to your 2)
point I've just noticed : nullptr
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.