functor #


functor(함수객체)는 함수의 인터페이스를 지원하는 객체를 말합니다.
구체적으로 말하면 class에 operator()를 overloading하여 사용하는
관용구를 말합니다.

#include <iostream>
#include <string>
using namespace std;


class Adder
{
public:
  Adder() {}
  ~Adder() {}

  int operator()(int lvalue, int rvalue)
  {
    return nSum_ = (lvalue + rvalue);
  }

  int operator()(int value)
  {
    return nSum_ += value;
  }

  int Result() const
  {
    return nSum_;
  }

private:
  int nSum_;

};


int FnAdd(int lvalue, int rvalue)
{
  return lvalue + rvalue;
}


int main()
{
  Adder add;

  cout << add(3, 6) << endl;
  cout << FnAdd(2, 4) << endl;

  cout << add(1) << endl;
  cout << add.Result() << endl;
}

위의 코드는 함수와 함수객체와의 단적인 확장성을 볼수 있습니다.

Adder객체는 함수 FnAdd와 인터페이스는 같으면서 두수를 더하고 그 결과를 리턴과
동시에 저장을 할수 있으며 그 결과값으로 다시 연산을 할수 있는
확장성을 보여줍니다.

예에서 볼수 있듯이 함수객체는 객체에 함수인터페이스를 추가함으로서
함수 호출 부분에 대신 들어가 더욱더 확장성 있는 일을 해낼수가 있습니다.


그리고 함수포인터로는 불가능한 inlining 작업을 수행함으로서 성능향상을
꽤할수도 있습니다.


#include <iostream>
#include <string>
using namespace std;


class Printer
{
public:
  Printer() {}
  ~Printer() {}

  template <class T>
  void operator()(const T &ty)
  {
    cout << ty << "!";
  }
};

void Print(int n)
{
  cout << n << ":";
}


template <class IterT, class FunT>
void ForEach(IterT begin, IterT end, FunT fun)
{
  while (begin != end) {
    fun(*begin++);
  }
}


int main()
{
  enum { ARR_SIZE = 5 };
  int nArr[ARR_SIZE] = { 1, 2, 3, 4, 5 };

  Printer printer;
  ForEach(nArr, nArr + ARR_SIZE, printer);
  cout << endl;

  ForEach(nArr, nArr + ARR_SIZE, Print);
  cout << endl;

  cin.get();
}

위의 Printer객체의 인스턴스인 printer는 void operator()(const T &ty) 가
인라인으로 되어 있어 ForEach 함수안에서 함수의 오버헤드 없이 호출이 되지만
Print함수는 앞에 inline키워드를 붙여 인라인을 강제하여도 함수포인터를 호출하려면
함수의 주소가 필요한 규칙에의해 컴파일러에게 인라인이 무시가 됩니다.


물론 인라인의 무절제한 사용으로 인한 성능 저하를 배제한다면 ...

'Dev > C++' 카테고리의 다른 글

explicit  (0) 2008.05.01
template  (0) 2008.05.01
Casting operators  (0) 2008.05.01
export  (0) 2008.05.01
main function  (0) 2008.05.01

+ Recent posts