std function

std::function°ú std::bind¸¦ ÀÌ¿ëÇÏ¸é ¸Þ¼Òµå Æ÷ÀÎÅ͸¦ °£´ÜÇÏ°Ô Ã³¸® ÇÒ¼ö ÀÖ´Ù.
¹Ù·Î ±¸ÇöÀ¸·Î ³Ñ¾î°£´Ù.

std::functionÀ» »ç¿ëÇÒ·Á¸é ´ÙÀ½°ú °°ÀÌ functional Çì´õ¸¦ Æ÷ÇÔ ½ÃŲ´Ù.

#include <functional>

1. °£´ÜÇÑ ÇÔ¼ö Æ÷ÀÎÅÍ ¿¹

#include <iostream>
#include <functional>

void Sub(int a, int b)
{
    printf("Sub : %d = %d - %d\n", a - b, a, b);
}

using  namespace  std::placeholders;
class Calculator
{
public:
    void Add(int a, int b) {
        printf("Add : %d = %d + %d\n", a+b, a, b);
    }

    void Func()
    {
        //std::function<void(int, int)> func = std::bind(&Calculator::Add, this, _1, _2);
        //auto¸¦ »ç¿ëÇÏÁö ¾ÊÀ¸¸é À§¿Í °°´Ù.
        auto func = std::bind(&Calculator::Add, this, _1, _2);
        func(11, 4);
    }
};

int main(int argc, const char * argv[])
{
    //1) ÇÔ¼ö Æ÷ÀÎÅÍ¿Í placeholders »ç¿ë
    auto subFunc1 = std::bind(Sub, _1, _2);
    subFunc1(50, 10);

    //2) ÇÔ¼ö Æ÷ÀÎÅÍ¿Í placeholders ÇÑ°³¸¸ »ç¿ë
    auto subFunc2 = std::bind(Sub, 100, std::placeholders::_1);
    subFunc2(10);

    //3) ¸Þ¼Òµå ÇÔ¼ö Æ÷ÀÎÅÍ·Î ÀÌ¿ë
    auto calc = Calculator();
    calc.Func();
    return 0;
}

1), 2)¹øÀº bind ÇÔ¼ö¸¦ ÅëÇØ ÇÔ¼ö Æ÷ÀÎÅ͸¦ º¯¼ö·Î °¡Áø´Ù.
    auto subFunc1 = std::bind(Sub, _1, _2);
    subFunc1(50, 10);


3) Ŭ·¡½ºÀ̸§::¸Þ¼Òµå¸í, °´Ã¼ÀÇ Æ÷ÀÎÅ͸¦ ³Ñ°ÜÁÖ¸é ¸Þ¼ÒµåÀÇ ÇÔ¼ö Æ÷ÀÎÅ͸¦ º¯¼ö·Î °¡Áø´Ù.
    //std::function<void(int, int)> func = std::bind(&Calculator::Add, this, _1, _2);
    auto func = std::bind(&Calculator::Add, this, _1, _2);

2. std::ref ÂüÁ¶¿¹

std::bind¸¦ ÅëÇØ °´Ã¼¸¦ ³Ñ±æ¶§´Â ÂüÁ¶·Î ³Ñ°Ü¾ß º¹»ç°¡ ¾ÈÀϾ´Ù.

//std::ref ÂüÁ¶¿¹
#include <iostream>
#include <functional>

using  namespace  std::placeholders;
class Calculator
{
public:
    void Add(int a, int b)
    {
        printf("Add : %d = %d + %d\n", a + b, a, b);
    }
};

int main(int argc, const char * argv[])
{
    Calculator calc;

    auto func1 = std::bind(&Calculator::Add, std::ref(calc), _1, 100);
    func1(200);

    int b = 10;
    auto func2 = std::bind(&Calculator::Add, std::ref(calc), _1, std::ref(b));
    func2(5);

}

calc °´Ã¼¸¦ ÂüÁ¶·Î ³Ñ±â°í ÀÖ´Ù.
auto func1 = std::bind(&Calculator::Add, std::ref(calc), _1, 100);

3. ¿¹ÀüÀÇ ÄÝ¹é ¹æ½Ä

std::function Áö¿ø ¾ÈµÉ¶§´Â ´ÙÀ½°ú °°ÀÌ ºÎ¸ðÀÇ ¼ø¼ö °¡»ó ÇÔ¼ö¸¦ ÅëÇØ ÄݹéÀ» ¸¹ÀÌ ±¸ÇöÇß´Ù.

#include <iostream>

class ICalc {
public:
    virtual void Callback(int a, int b) = 0;
};

class Calculator : public ICalc
{
public:
    void Callback(int a, int b) {
        printf("Add : %d = %d + %d\n", a + b, a, b);
    }
};

void AddFunc(ICalc* calc)
{
    calc->Callback(22, 33);
}

int main(int argc, const char * argv[])
{
    Calculator calc;
    AddFunc(&calc);
    return 0;
}

4. std::functionÀ¸·Î °£´ÜÇÏ°Ô ÄÝ¹é ±¸Çö

#include <iostream>
#include <functional>

using  namespace  std::placeholders;
class Calculator
{
public:
    int Add(int a, int b)
    {
        printf("Calculator Add : %d = %d + %d\n", a + b, a, b);
        return (a + b);
    }
};

class Computer
{
public:
    int Add(int a, int b)
    {
        printf("Computer Add : %d = %d + %d\n", a + b, a, b);
        return (a + b);
    }
};

int AddFunc(std::function<int(int, int)> f)
{
    return f(100, 33);
}

int main(int argc, const char * argv[])
{
    Calculator calc;
    auto func1 = std::bind(&Calculator::Add, std::ref(calc), _1, _2);
    int a1 = AddFunc(func1);

    Computer comp;
    auto func2 = std::bind(&Computer::Add, std::ref(comp), _1, _2);
    int a2= AddFunc(func2);
    printf("Result :  %d , %d\n", a1, a2);

    //Lamda¸¦ ÅëÇØ
    //[introducer capture] (parameters) -> return type { Code }
    AddFunc(
        [](int a, int b) -> int {
        printf("Lamda Add : %d = %d + %d\n", a + b, a, b);
        return (a + b);
    });
}

std::fuction º¯¼ö¸¦  AddFunc  Äݹé ÇÔ¼ö·Î ³Ñ°ÜÁÖ°í ÀÖ´Ù.
    Calculator calc;
    auto func1 = std::bind(&Calculator::Add, std::ref(calc), _1, _2);
    int a1 = AddFunc(func1);

std::function º¯¼ö´Â ¶÷´Ù ÇÔ¼ö¸¦ ³Ñ°Üµµ µÈ´Ù.
    AddFunc(
        [](int a, int b) -> int {
        printf("Lamda Add : %d = %d + %d\n", a + b, a, b);
        return (a + b);
    });  }