C#은 안전한 함수 포인터 개체를 정의하는 delegate 형식을 제공한다. C++ 사용자정의함수에서 파라미터로 함수를 입력받기 위해 사용하는 개념과 동일하다. c#에서는 delegate를 선언하고 사용하는 과정을 간소화하여 Action, Func, Predicate를 제공하고 있다. 참고로 delegate는 이벤트에서 사용하므로 C#에서 이해는 필수이다.
C++의 함수 포인터를 C#의 Func
으로 표현해 보는 몇 가지 예제를 작성하였다. 특히 C++의 함수 포인터 예제는 유튜브 C/C++ 강좌로 유명한 두들낙서 94강. 함수 포인터를 참고하였다. Rust 예제포함.
Example 1 (C++, C#)
#include <iostream>
#include <string>
using namespace std;
bool compare(int a, int b)
{
return a == b;
}
int main(void)
{
bool (*fp)(int, int) = compare;
bool result = fp(2, 2);
cout << result << endl;
cout << boolalpha << result << endl;
cout << string(result ? "True" : "False") << endl;
}
void Main()
{
Func<int, int, bool> func = compare;
bool result = func(2, 2);
(result ? 1 : 0).Dump();
result.Dump();
}
bool compare(int a, int b)
{
return a == b;
}
Example 2 (C++, C#)
#include <iostream>
using namespace std;
int square(int x)
{
return x * x;
}
int myFunc(int x)
{
return x * (x - 15) / 2;
}
int cube(int x)
{
return x * x * x;
}
int arrFnMin(const int arr[], int n, int (*f)(int))
{
int min = f(arr[0]);
for (int i = 1; i < n; i++)
{
if (f(arr[i]) < min)
{
min = f(arr[i]);
}
}
return min;
}
int main(void)
{
int arr[7] = {3, 1, -4, 1, 5, 9, -2};
cout << arrFnMin(arr, 7, square) << endl;
cout << arrFnMin(arr, 7, myFunc) << endl;
cout << arrFnMin(arr, 7, cube) << endl;
return 0;
}
void Main()
{
int[] arr = { 3, 1, -4, 1, 5, 9, -2 };
ArrFnMin(arr, 7, Square).Dump();
ArrFnMin(arr, 7, MyFunc).Dump();
ArrFnMin(arr, 7, Cube).Dump();
"----------".Dump();
ArrFnMin(arr, Square).Dump();
ArrFnMin(arr, MyFunc).Dump();
ArrFnMin(arr, Cube).Dump();
}
int Square(int x)
{
return x * x;
}
int MyFunc(int x)
{
return x * (x - 15) / 2;
}
int Cube(int x)
{
return x * x * x;
}
int ArrFnMin(int[] arr, int n, Func<int, int> func)
{
int min = func(arr[0]);
for (int i = 1; i < n; i++)
{
if (func(arr[i]) < min)
{
min = func(arr[i]);
}
}
return min;
}
int ArrFnMin(ReadOnlySpan<int> arr, Func<int, int> func)
{
int min = func(arr[0]);
foreach (int item in arr[1..])
{
if (func(item) < min)
{
min = func(item);
}
}
return min;
}
Rust Example
fn compare(a: i32, b: i32, check: fn(x: i32, y: i32) -> bool) -> bool {
check(a, b)
}
fn main() {
println!("{}", compare(2, 2, |a, b| a == b));
}
use winsafe::OutputDebugString;
fn square(x: i32) -> i32 {
x * x
}
fn my_func(x: i32) -> i32 {
x * (x - 15) / 2
}
fn cube(x: i32) -> i32 {
x * x * x
}
fn arr_min1(arr: Box<[i32]>, arr_fn: fn(i32) -> i32) -> i32 {
let mut min = arr_fn(arr[0]);
for i in 1..arr.len() {
if arr_fn(arr[i]) < min {
min = arr_fn(arr[i]);
}
}
min
}
fn arr_min2(arr: &Vec<i32>, arr_fn: fn(i32) -> i32) -> i32 {
let mut min = arr_fn(arr[0]);
for i in 1..arr.len() {
if arr_fn(arr[i]) < min {
min = arr_fn(arr[i]);
}
}
min
}
fn main() {
let f = arr_min1;
let arr = [3, 1, -4, 1, 5, 9, -2];
let debug = &f(arr.into(), square).to_string()[..];
println!("{}", debug);
OutputDebugString(debug);
println!("{}", f(arr.into(), my_func));
println!("{}", f(arr.into(), cube));
let f = arr_min2;
let arr = vec![3, 1, -4, 1, 5, 9, -2];
println!("{}", f(&arr, square));
println!("{}", f(&arr, my_func));
println!("{}", f(&arr, cube));
}
참고할 만한 강좌(링크)