How to write C function accepting (one) argument of any type

孤街浪徒 提交于 2019-12-05 05:13:34

You could instead try implementing your function similar to a generic function like bsearch, which can perform a binary search on an array of any data type:

void *bsearch(const void *key, const void *base, size_t nmemb, size_t size,
              int (*compar)(const void *, const void *))

Rather than hard-coding the different implementations for different data types inside your function, you instead pass a pointer to a function which will do the type-dependent operation, and only it knows the underlying implementation. In your case, that could be some sort of traversal/iteration function.

The other thing bsearch needs to know (apart from the obvious - search key and array length) is the size of each element in the array, so that it can calculate the address of each element in the array and pass it to the comparison function.


If you had a finite list of types that were to be operated on, there's nothing wrong with having a family of findX() functions. The above method requires a function for each data type to be passed to the bsearch function, however one of the main differences is that common functionality doesn't need to be repeated and the generic function can be used for any data type.

I wouldn't really say there's any proper way to do this, it's up to you and really depends on the problem you're trying to solve.

I am not sure whether answering my own question is polite, but I want your opinion.

I tried to solve this problem using va_list. Why so? Because this way I can write only one function. Please, mind that I know what type the argument should be. This way I can do this:

    int find(void* list, ...) {
      any_type object = {0};
      int i = -1;
      va_list args;
      va_start(args, list);
      switch(type_of_elem(list)) {
        case INT: object.i = va_arg(args, int); break;
        ...
      }
      /* now &object is pointer to memory ready for comparision
       * f.eg. using memcmp */
      return i;
    }

The advantage of this solution is that I can wrap presented switch-case and reuse it with other functions.

After researching a little bit more on my concern regarding no limit on number of arguments I realized that printf lacks this limit either. You can write printf("%d", 1, 2, 3). But I tweaked my solution with additional macro:

    #define find_(list, object) find((list), (object))

Which produces error message at compile time, saying that find_ macro expects 2 arguments not 3.

What do you think about it? Do you think this is better solution than previously suggested?

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!