programing

C의 유사 제네릭

minimums 2023. 10. 10. 20:13
반응형

C의 유사 제네릭

저는 다양한 종류의 숫자 배열로 작업을 수행하는 몇 가지 방법을 구현해야 합니다.보통은 그 일에 제네릭을 사용하지만 C가 제공하지 않기 때문에 매크로를 사용하여 에뮬레이션을 시도하고 있습니다.

다음은 제가 하려는 일의 예입니다.

#ifndef TYPE
#define TYPE int
#endif

TYPE get_minimum_##TYPE (TYPE * nums, int len){
    TYPE min = nums[0];

    for (int i = 1; i < len; i++) {
        if (nums[i] < min) {
            min = nums[i];
        }
    }

    return min;
}

그러나 이것은 컴파일되지 않습니다.clang 오류 메시지:

오류: 최상위 수준 선언자 뒤에 ';'가 필요합니다.

이것을 C에서 할 수 있는 방법이 있습니까?아니면 이것을 모든 종류에 대해 수작업으로 실행해야 합니까?

헤더 파일에서 다음과 같은 작업을 수행할 수 있습니다.

//
// generic.h
//

#define TOKENPASTE(x, y) x ## y

#define GET_MINIMUM(T) TOKENPASTE(get_minimum_, T)

TYPE GET_MINIMUM (TYPE) (TYPE * nums, size_t len){
    TYPE min = nums[0];

    for (size_t i = 1; i < len; i++) {
        if (nums[i] < min) {
            min = nums[i];
        }
    }

    return min;
}

그리고 나서.#include필요한 각 유형별로 소스 파일에 저장됩니다. 예:

//
// generic.c
//

#define TYPE int
#include "generic.h"
#undef TYPE

#define TYPE float
#include "generic.h"
#undef TYPE

이는 전처리기를 통해 실행하여 테스트할 수 있습니다.

$ gcc -E generic.c 

int get_minimum_int (int * nums, size_t len){
    int min = nums[0];

    for (size_t i = 1; i < len; i++) {
        if (nums[i] < min) {
            min = nums[i];
        }
    }

    return min;
}

float get_minimum_float (float * nums, size_t len){
    float min = nums[0];

    for (size_t i = 1; i < len; i++) {
        if (nums[i] < min) {
            min = nums[i];
        }
    }

    return min;
}

실제로, 주어진 유형에 대해 함수를 생성할 매크로를 정의하는 것이 최선입니다.

#define define_get_minimum(T) \
T get_minimum_##T(T* nums, int len){ \
    T min = nums[0]; \
    for (int i = 1; i < len; i++) { \
        if (nums[i] < min) { \
            min = nums[i]; \
        } \
    } \
    return min; \
}

그런 다음 해당 매크로를 호출하여 필요한 전문화를 정의할 수 있습니다(C++ 템플릿을 사용하면 비슷한 작업이 컴파일러에 의해 자동으로 수행됩니다).

define_get_minimum(int)
define_get_minimum(double)
define_get_minimum(float)

C++ 컴파일러가 자동으로 수행하는 또 다른 일은 필요한 오버로드 함수를 추론하는 것입니다.C에서는 그런 것을 가질 수 없기 때문에, it 전문화를 사용하고 있다고 말해야 할 것입니다.다음 매크로(C++)를 사용하여 함수에 대한 템플릿 같은 구문을 시뮬레이션할 수 있습니다.<>로 대체됩니다.()):

#define get_minimum(T) get_minimum_##T

그렇다면 다음과 같이 부를 수 있을 것입니다.

int main()
{
    // Define arr as char* array...
    // Do stuff...
    int res = get_minimum(int)(arr, 3);
}

이 코드를 테스트하지는 않았지만 작동이 될 것입니다.

또한 switch 문 이외의 함수 포인터(Array of function pointers)를 사용하고 switch의 인수를 인덱스로 배열에 전달할 수도 있습니다.

언급URL : https://stackoverflow.com/questions/16522341/pseudo-generics-in-c

반응형