2010-05-23 4 views

답변

-1
template <typename T> 
void echo_tpl(const T& t) { std::cout << t; } 

편집 : c 태그를 발견하지 못했습니다. 위의 대답은 C++에서만 작동합니다.

+0

이 C++이 아닌가요? – httpinterpret

+0

예. 그 이유는 내 비슷한 대답을 삭제 ... –

8

C에는 템플릿이 없습니다. 나는 당신이 할 수있는 최선의 방법은 유니온을 사용하거나 함수의 이름을 다르게하는 것입니다. 다른 이름을 갖는 후자의 방법이있을 경우

void echo_tpl_s(char const *string) { /* ... */ } 
void echo_tpl_i(int number) { /* ... */ } 

int main(void) { 
    echo_tpl_s("Hello world"); 
    echo_tpl_i(42); 
} 

(예 로서도 기능을 오버로드 할 수없는 사실 C 차지 OpenGL을 의해서도 heavily usedfabsfabsffabsl 대해)를 수행하는 준 표준 방법 공통 코드의 많은, 당신은 별도의 기능

void echo_tpl_s(char const *string) { 
    prepare_output_device(); 
    printf("%s", string); 
    unprepare_output_device(); 
} 

void echo_tpl_i(int number) { 
    prepare_output_device(); 
    printf("%d", number); 
    unprepare_output_device(); 
} 

또는에서 그것을 고려하기로 결정할 수있다 당신은 일을 할의 조합 방법을 취할 수 함수 이름은 동일하지만 메타 정보로 매개 변수 유형을 날려 버립니다. 당신이 어딘가에 값을 저장 한 다음 그것을 통과 어떤 값 유형을 돌보는없이 인쇄 기능을 실행하려면

enum Type { 
    Number, 
    String 
}; 

struct Value { 
    enum Type type; 
    union { 
    int number; 
    char const *string; 
    } u; 
}; 

void echo_tpl(struct Value value) { 
    switch(value.type) { 
    case Number: printf("%d", value.u.number); break; 
    case String: printf("%s", value.u.string); break; 
    } 
} 

int main(void) { 
    echo_tpl((struct Value) { 
    .type = String, 
    .u.string = "Hello world" 
    }); 
} 

노조 방법은 매우 적합 특히입니다. 이 복합 리터럴

int main(void) { 
    struct Value value; 
    value.type = String; 
    value.u.string = "Hello world"; 
    echo_tpl(value); 
} 

그것은 그것을위한 기능을 만드는 것이 좋습니다

이 없기 때문에

struct Value stringval(char const *string) { 
    struct Value value; 
    value.type = String; 
    value.u.string = string; 
    return value; 
} 

struct Value numberval(int number) { 
    struct Value value; 
    value.type = Number; 
    value.u.number = number; 
    return value; 
} 

int main(void) { 
    echo_tpl(stringval("Hello world!")); 
} 

어떤 컴파일러가 제공 할 수 있지만 C89에서는 별도로 값을 만들어야합니다 그러한 것들을 쓰기위한 확장. 예 Clang는 C.

void echo_tpl(int value) __attribute__((overloadable)) { 
    printf("%d", value); 
} 

void echo_tpl(char const *value) __attribute__((overloadable)) { 
    printf("%s", value); 
} 

function overloading 제공 위해이 함수의 호출 측의 종류에 의존하지 해결한다. 정의 측면에서 코드를 두 번 작성해야합니다. 그 이유는 주로 C가 유형 제네릭 출력 함수를 가지고 있지 않기 때문입니다. 물론이 기능을 사용하면 코드가 옮겨 질 수 없게됩니다.

+0

+1, 나는 노조를 사용하는 것이 좋습니다. –

+0

이 방법은 64 비트 시스템에서는 괜찮습니까? –

+0

@Gary 두 기술 모두 64 비트 시스템에서 사용할 수 있습니다. 노동 조합원은 같은 크기를 가질 필요가 없습니다. –

4

템플릿을 C로 변환하는 전통적인 방법은 전 처리기를 사용하는 것입니다. 나는 단지 가정 유형은 1입니다 좀 더 복잡한 유형 맹 글링 규칙을 원래의 C++ 컴파일러 처리 템플릿, 그들 만이 가지고 어떻게 이것은

// this creates each template "instance" 
#define ECHO_TPL_IMPLEMENT(t) void echo_tpl_##t(t param){\ 
/* this is where you write your function that uses param */ \ 
} 

// this calls the specific template instance 
#define ECHO_TPL(t, val) echo_tpl_##t(val) 

// as i wrote it, the function only accepts a 1 word parameter type 
// so for simplicity, i'm defining char* to be string 
typedef char *string; 

// i implement the function for the types int and string 
ECHO_TPL_IMPLEMENT(int)  // creates echo_tpl_int 
ECHO_TPL_IMPLEMENT(string) // creates echo_tpl_string 

main() 
{ 
    // then i just call them and let the preprocessor handle it 
    ECHO_TPL(string, "meep"); // will call echo_tpl_string 
    ECHO_TPL(int, 10);   // will call echo_tpl_int 
} 

(아직도이 일을 어떻게) :이처럼 뭔가를 할 거라고 단어가 맞는지 확인하고, 그렇지 않은 경우 을 입력해야합니다.

편집 : 기능을 비워 둡니다. 이것은 실제로 C에서 "템플릿 함수"를 작성하는 방법이지만 C가 유형 독립적 인 API 작성 API를 가지고 있지 않기 때문에 실제로 매개 변수를 쓰지 않습니다.printfwrite은 실제 유형에 대한 정보가 필요합니다 (%d 또는 %s 및 각각 쓸 내용의 바이트 길이를 통해).

또한 C++에도 적용됩니다. 템플릿에서 파일에 쓰려면 C API를 사용할 수 없으며 실제로는 cout (또는 부스트 형식 대체 또는 이와 유사한 형식) 만 사용할 수 있습니다. 실제 기능으로 무엇을하고 싶은지 생각해야합니다.

+0

맞아요, 늦었어요. ( – Blindy

0

C11 표준에서 C는 이제 _Generic 표현식을 사용하여 오버로드에 대한 일부 제한적 지원을 가지며 입력 유형에 따라 컴파일시 올바른 결과 표현식을 선택합니다. 템플릿 같은 것도 있지만이 같은이 오래된 질문에 대한 답변 수 :

#define echo_tpl(X) _Generic((X), int: echo_tpl_i, \ 
           char *: echo_tpl_s)(X) 

void echo_tpl_s(char const *string) { /* ... */ } 
void echo_tpl_i(int number) { /* ... */ } 

int main(void) { 
    echo_tpl("Hello world"); 
    echo_tpl(42); 
} 

당신은 아직도 당신이 C99에서와 같이 별도의 이름을 사용하여 기능 구현을 정의 할 필요가 있지만, ++는 C와 매크로 정의 할 수 있습니다 - 분에 이름을 그 함수 사용자가 인수 유형에 대해 생각하지 않고 해당 호출 사이트에 적합한 버전을 선택하기 위해 모든 사용 지점에 _Generic 표현식을 삽입합니다.

C 표준이 완전히 채택되기까지는 겉으로보기에는 영원히 필요하며 어떤 컴파일러가이 기능을 구현하는지 전혀 알지 못합니다. 그러나 더 많은 사람들이 나가서 사용하면 더 빨리 확산 될 것입니다!

관련 문제