Składnia i przykładowe użycie Generic w C11
Słyszałem, że C11 dodaje generyki. Trochę wygooglowałem, przejrzałem kilka artykułów, zrozumiałem, że jest nowe słowo kluczowe (_Generic
) i w ogóle. Ale nie mogę pojąć wszystkiego.
Czy to coś jak generyki w C# czy szablony w C++? Czy ktoś może mi podać krótkie wyjaśnienie definicji C11 generyków, jej składni i prostego przykładowego przykładu użycia?
3 answers
To {[6] } jest całkiem dobrym wstępem. Oto przegląd:
Wybór generyczny jest zaimplementowany za pomocą nowego słowa kluczowego: _Generic. Składnia jest podobna do prosta instrukcja switch dla typów:
_Generic( 'a', char: 1, int: 2, long: 3, default: 0)
ocenia do 2 (stałe znaków są ints w C).
W zasadzie działa jak rodzaj switch
, Gdzie etykiety są nazwami typów, które są testowane względem typu pierwszego wyrażenia ('a'
powyżej). Wynik staje się wynikiem oceny _Generic()
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-21 12:22:30
Najlepszy przykład jaki widziałem zainspirował poniższy (uruchamialny) przykład, który odblokowuje wszelkiego rodzaju dziwaczne możliwości pękniętej introspekcji...
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#define typename(x) _Generic((x), /* Get the name of a type */ \
\
_Bool: "_Bool", unsigned char: "unsigned char", \
char: "char", signed char: "signed char", \
short int: "short int", unsigned short int: "unsigned short int", \
int: "int", unsigned int: "unsigned int", \
long int: "long int", unsigned long int: "unsigned long int", \
long long int: "long long int", unsigned long long int: "unsigned long long int", \
float: "float", double: "double", \
long double: "long double", char *: "pointer to char", \
void *: "pointer to void", int *: "pointer to int", \
default: "other")
#define fmt "%20s is '%s'\n"
int main() {
size_t s; ptrdiff_t p; intmax_t i; int ai[3] = {0}; return printf( fmt fmt fmt fmt fmt fmt fmt fmt,
"size_t", typename(s), "ptrdiff_t", typename(p),
"intmax_t", typename(i), "character constant", typename('0'),
"0x7FFFFFFF", typename(0x7FFFFFFF), "0xFFFFFFFF", typename(0xFFFFFFFF),
"0x7FFFFFFFU", typename(0x7FFFFFFFU), "array of int", typename(ai));
}
╔═══════════════╗ ═════════════════╣ Amazeballs... ╠═════════════════════════════════════ ╚═══════════════╝ size_t is 'unsigned long int' ptrdiff_t is 'long int' intmax_t is 'long int' character constant is 'int' 0x7FFFFFFF is 'int' 0xFFFFFFFF is 'unsigned int' 0x7FFFFFFFU is 'unsigned int' array of int is 'other'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-27 03:05:42
Używam clion 1.2.4, a clion nie obsługuje teraz c11, więc używam poniższego kodu w c99 zamiast _Generic
#include <stdio.h>
int main(int argc, char **argv) {
char *s;
if (__builtin_types_compatible_p(__typeof__(s), long)) {
puts("long");
} else if (__builtin_types_compatible_p(__typeof__(s), char*)) {
puts("str");
}
return (0);
};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-19 13:38:38