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
'programing' 카테고리의 다른 글
봄 mvc에서 서블릿 3.1을 사용하는 방법? (0) | 2023.10.15 |
---|---|
SQLLlchemy: 적어도 하나의 다대다 관련 테이블에서 멤버 자격으로 필터링 (0) | 2023.10.15 |
Node.js를 확인하는 방법: "오류: ENOENT: 해당 파일 또는 디렉토리가 없습니다." (0) | 2023.10.10 |
스위프트 변수가 원자인가요? (0) | 2023.10.10 |
Chrome 버전 58의 리액터 편집기 텍스트 형식 문제 (0) | 2023.10.10 |