You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中带未知类型参数的泛型函数实现及扩展应用咨询

Making Your Generic for_each Function More Versatile

Great question—this is a classic hurdle when writing generic code in C, since the language lacks built-in parametric polymorphism like higher-level languages. Let's walk through practical ways to make your for_each function work seamlessly with more functions (like math operations) without writing tedious wrapper functions manually.

1. Auto-Generate Wrappers with Macros

The most straightforward fix for reducing boilerplate is to use a macro that dynamically creates the wrapper function you need based on the target function's argument type. This eliminates manual repetition while keeping your original for_each function intact.

Here's the macro:

#define GENERATE_WRAPPER(wrapper_name, target_func, arg_type) \
void wrapper_name(void *arg) { \
    target_func(*(arg_type*)arg); \
}

Example Usage

For close(int fd):

// Auto-generate the close wrapper—no manual code needed!
GENERATE_WRAPPER(close_fd, close, int)

// For a math function like sqrt(double)
GENERATE_WRAPPER(sqrt_wrapper, sqrt, double)

int main() {
    // Example array of file descriptors (storing pointers to ints)
    int fds[] = {1, 2, 3};
    void* fd_array[] = {(void*)&fds[0], (void*)&fds[1], (void*)&fds[2], NULL};
    for_each(fd_array, close_fd);

    // Example array of doubles for sqrt
    double nums[] = {4.0, 9.0, 16.0};
    void* num_array[] = {(void*)&nums[0], (void*)&nums[1], (void*)&nums[2], NULL};
    for_each(num_array, sqrt_wrapper);

    return 0;
}

2. Use C11 _Generic for Compile-Time Type Matching

If you're working with C11 or later, _Generic lets you create type-aware macros that eliminate wrapper functions entirely. This approach is cleaner at the call site and keeps type safety checks at compile time.

Generic for_each Macro

Replace your standalone for_each function with a macro that handles type conversion directly:

#define FOR_EACH_GENERIC(array, func, elem_type) \
    for (size_t i = 0; array[i] != NULL; ++i) { \
        func(*(elem_type*)array[i]); \
    }

Example Usage

Now you can call it directly without any wrappers:

int main() {
    int fds[] = {1, 2, 3};
    void* fd_array[] = {(void*)&fds[0], (void*)&fds[1], (void*)&fds[2], NULL};
    // Directly pass the function and type
    FOR_EACH_GENERIC(fd_array, close, int);

    double nums[] = {4.0, 9.0, 16.0};
    void* num_array[] = {(void*)&nums[0], (void*)&nums[1], (void*)&nums[2], NULL};
    FOR_EACH_GENERIC(num_array, sqrt, double);

    return 0;
}

3. Extend for_each with User Data (For Advanced Flexibility)

If you need even more control (e.g., passing additional parameters to the target function), modify your for_each to accept a void* user_data parameter. This lets you pass context or type info to your wrapper functions.

Updated for_each Function

void for_each(void *array[], void (*func)(void *, void *), void *user_data) {
    for (size_t i = 0; array[i] != NULL; ++i) {
        func(array[i], user_data);
    }
}

Generic Wrapper Macro for This Version

#define GENERATE_CONTEXT_WRAPPER(wrapper_name, target_func, arg_type) \
void wrapper_name(void *arg, void *user_data) { \
    // Use user_data if you need extra parameters—here we ignore it for simplicity
    (void)user_data; \
    target_func(*(arg_type*)arg); \
}

Example Usage

GENERATE_CONTEXT_WRAPPER(close_fd_ctx, close, int)

int main() {
    int fds[] = {1, 2, 3};
    void* fd_array[] = {(void*)&fds[0], (void*)&fds[1], (void*)&fds[2], NULL};
    for_each(fd_array, close_fd_ctx, NULL);

    return 0;
}

Key Notes to Avoid Bugs

  • Type Safety: Always ensure your void* array stores pointers to the correct type—never cast non-pointer values (like raw int fds) directly to void* (this is non-portable and risky).
  • Termination Condition: Your array[i] != NULL check relies on the array ending with a NULL pointer—make sure this is consistent across all uses.
  • Function Signatures: The target function must accept a single argument of the type you specify (adjust the macros if you need functions with multiple arguments).

内容的提问来源于stack exchange,提问作者B14s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:12:26