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));
}
참고할 만한 강좌(링크)
 MSJO.kr