void pointers and function pointers in structure members
Hello I have following code.
typedef struct __vector {
int (*container_end) ( struct __vector *);
}vector;
and another iterator structure with following declaration :
typedef struct __iterator {
void *ptr_to_container;
int (*end)(struct __iterator *);
}iterator;
int
end(iterator *itr) {
return (itr->ptr_to_container)->container_end(itr->ptr_to_container);
}
This code does not compile as ptr_to_container
is void pointer.
Is there any work-around to this problem.
container_end
function will be define开发者_如何转开发d separately and ptr_to_container
will point to some container.
thanks Avinash
It looks like you have missed something when defining the iterator structure. Why does the iterator have a function pointer to an 'end' function that accepts an iterator?
If you want it to be really generic, you could perhaps use this definition instead:
typedef struct __iterator {
void * ptr_to_container;
int (*end)(void *);
} iterator;
int end(iterator * it) { return it->end(it->ptr_to_container)); }
In the vector definition (and other data types), you can then define a function to create an iterator:
static int vector_end(vector * v) { /* implementation omittted */ }
iterator * vector_create_iterator(vector * v)
{
iterator * it = malloc(sizeof(iterator));
it->ptr_to_container = v;
it->end = vector_end;
return it;
}
However, the solution really depends on how the data structures are defined. In the above suggestion, it is up to each data structure to provide an implementation for how to traverse it.
As an alternative, you could set up a generic data structure interface, like
typedef struct _container container;
struct _container {
int (*end)(container * c);
};
Then the vector implementation would "only" have to fill in this container structure:
typedef struct _vector {
container c;
/* other fields required by the vector */
}
static int vector_end(container * c)
{
vector * v = (vector *) c;
...
}
container * create_vector()
{
vector * v = malloc(sizeof(vector));
v->c.end = vector_end;
return v;
}
...and the iterator could work with just the generic container:
typedef struct _iterator {
container * c;
/* other fields used by the iterator, such as current position */
}
int end(iterator * it) { return it->c->end(it->c); }
From the code sample in the question, it looks almost like you have mixed up these two approaches :-)
Did you try casting to a vector *?
return ((vector *)(itr->ptr_to_container))->containter_end(itr->ptr_to_container);
However, are you sure you want to do this? You are using itr to call a function and then pass itr to that function. Including more context (more code) would help.
You need to explicitly cast *ptr_to_container to a vector pointer:
((__vector *)(itr->ptr_to_container))->container_end
Otherwise the compiler doesn't know what is the structure of the target.
Though, I don't really see why you want to have such a construction. It looks like you want to have object orientation here with inheritance, but without explicitly stating anything. It won't work well. In C, you'll have to use less general structures, or move to C++.
If it must be void *
use
int
end(iterator *itr) {
return ((vector)(itr->ptr_to_container))->container_end(itr->ptr_to_container);
}
or else specify in the iterator that it is a vector iterator
typedef struct __iterator {
vector *ptr_to_container;
int (*end)(struct __iterator *);
}iterator; //probably you'll need to rename to make type of iterator clear
If you need to keep the abstraction (one iterator for all of you containers) nothing comes to mind atm...
精彩评论