Last active
April 15, 2022 02:34
-
-
Save koturn/5013105 to your computer and use it in GitHub Desktop.
C言語におけるラムダを関数マクロで実現したものです。 GNU拡張文法(複文の式化、関数内の関数定義)を用いているので、gccでしか用いることができません。 また、トップレベルで用いることも不可能です。
C++でもコンパイルエラーにならないように、C++0xのラムダに変換するようにしています。 利便性を考え、ある程度の省略表記を許すようにしています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
/*! | |
* @brief GNU拡張機能を用いたラムダ関数を実現するマクロ | |
* | |
* gccもしくはC++0x対応コンパイラでのみコンパイル可能<br> | |
* トップレベルで用いることはできない | |
* @param [in] rettype 返り値の型 | |
* @param [in] ARG_LIST 関数の引数.丸括弧が必要 | |
* @param [in] BODY 関数本体。中括弧が必要 | |
* @return 定義した無名関数へのポインタ | |
*/ | |
#if defined(__cplusplus) // C++は、C++0xのラムダを用いる | |
# define LAMBDA(rettype, ARG_LIST, BODY) \ | |
([&]ARG_LIST -> rettype { BODY; } ) | |
#elif defined(__GNUC__) && !defined(__clang__) | |
# define LAMBDA(rettype, ARG_LIST, BODY) \ | |
({ \ | |
rettype __lambda_funcion__ ARG_LIST { BODY; } \ | |
__lambda_funcion__; \ | |
}) | |
#endif | |
/*! | |
* @brief プログラムのエントリポイント | |
* @return 終了コード | |
*/ | |
int main(void) { | |
int i; | |
int array[5] = {4, 1, 7, -2, 3}; | |
int len; | |
// 関数ポインタに無名関数を渡す例 | |
int (*sum)(int, int, int) = LAMBDA(int, (int a, int b, int c), { | |
return a + b + c; | |
}); | |
// 関数ポインタに格納した無名関数を呼び出す | |
printf("2 + 3 + 5 = %d\n", sum(2, 3, 5)); | |
// その場で無名関数を呼び出す例1 | |
len = LAMBDA(int, (const char *str1, const char *str2), { | |
return strlen(str1) - strlen(str2); | |
})("Hello", "World!"); | |
printf("difflen = %d\n", len); | |
// その場で無名関数を呼び出す例2 | |
printf("6 - 1 = %d\n", LAMBDA(int, (int a, int b), { | |
return a - b; | |
})(6, 1)); | |
// qsort()関数の第4引数に渡す例 | |
qsort(array, (sizeof(array) / sizeof(array[0])), sizeof(array[0]), | |
LAMBDA(int, (const void *a, const void *b), { | |
return *(int *)a - *(int *)b; | |
}) | |
); | |
for (i = 0; i < (sizeof(array) / sizeof(array[0])); i++) { | |
printf("array[%d] = %d\n", i, array[i]); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment