rsjethani
rsjethani

Reputation: 2227

Is there a way to get template effect in C?

I've developed a C dll containing simple link list functions but they all are defined on int type i.e. when ever the user will create a link list using my library he can only created a list of ints.So what if I could do something(except void*) to let the user create a list of arbitrary data types say char,float or even user define struct?That too without recompilation.

thanks.

Upvotes: 3

Views: 266

Answers (7)

luser droog
luser droog

Reputation: 19494

I agree with the other answers that void * is the only way to go. But you can squeeze more dynamic behavior without recompiling if you add a size parameter that indicates how many bytes the void * points to.

void *shift(list *plist, unsigned size);
void unshift(list *plist, void *item, unsigned size);

Then you can hide the size with macros.

#define Cshift(L)   shift(L,sizeof(char))
#define Cunshift(L,I) unshift(L,I,sizeof(char))

Upvotes: 1

Nick
Nick

Reputation: 5805

Using macros is a decent approach to templatizing definitions, i.e. generating any number of definitions based on a pattern. Here is an example -- but it is ugly as hell.

#include <stdlib.h>

#define template_struct_A(T1,T2) struct A_ ## T1 ## _ ## T2 { \
    T1 a; \
    T2 b; \
}
#define struct_A(T1,T2) struct A_ ## T1 ## _ ## T2

struct C { const char*s; };

typedef const char* pchar;
template_struct_A(int, pchar); // explicit instantiation of struct A<int, pchar>

int main() {
    struct X { struct C x; } x;
    struct_A(int, pchar) o1; // struct A<int, const char*> o1
    o1.a = 1;
    o1.b = "hello";

    struct_A(int, pchar) o2; // struct A<int, const char*> o2
    o2.a = o1.a * 2;
    o2.b = "world";

    typedef struct_A(int, pchar)* pAInt;
    typedef struct C structC;
    template_struct_A(pAInt, structC) o3; // struct A<struct A<int, const char*>, struct C> o3
    o3.a = &o2;
    o3.b.s =  "hi";

    printf ("o1.a = %d, o1.b = %s, o2.a = %d, o2.b = %s, o3.b.s = %s\n", o1.a, o1.b, o2.a, o2.b, o3.b.s);
}

Upvotes: 3

Kerrek SB
Kerrek SB

Reputation: 476990

You could essentially rewrite C++ in C, to whichever level of detail you need. You could start with making the linked list's data type a struct * to some wrapper structure which itself could contain a type identifier and a void pointer to the actual data. You could write your own vtable to allow for polymorphism, and you could add reference counting and memory management... none of that is magic, so if you really need that sort of generality, you could certainly write it all in C. Or just use C++ :-)

Upvotes: 0

Christian Rau
Christian Rau

Reputation: 45948

You could use macros. For example you can make different list node types, with differently typed data members and keep sure all have a next and prev member. Then just use macros for all the list operations (like add, insert, remove), as these don't care about the type stored.

Of course macros aren't that type safe as templates and are considered "bad style". But hey we're in C, who fears macros in C? And void* isn't that type safe, too.

Upvotes: 0

blaze
blaze

Reputation: 4364

There is no way to do it at runtime without void *. But there is way to do it without separately compiled code: all operations can be #define.

http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/queue.h?rev=1.75;content-type=text%2Fx-cvsweb-markup

Upvotes: 0

Matt Joiner
Matt Joiner

Reputation: 118490

Language/Compiler Support

Examples

Upvotes: 1

Williham Totland
Williham Totland

Reputation: 29009

The only option, apart from void * is, well, nothing.

The only option is void *, is what I'm saying.

void * is the only generic type in C; and to a degree, also the only generic degree in C++; as neither are what you would call dynamic languages.

Of course, if you were feeling particularly crazy, you could readjust your internal struct for linked list links to include a union, and have a series of functions named as

add_<type>_to_list(); // <type> = char, int, float…

But that's not likely to give satisfactory results.

Upvotes: 1

Related Questions