C++0x で関数へのポインタによるコールバックをインライン化する

お題

http://d.hatena.ne.jp/Cryolite/01000831#p1
C++0x によって実現してみる。

解答1

Variadic Templates を使う。

#include <utility>

template<class F, F f>
class il_ptr_fun;

// とりあえず関数ポインタだけ
template<class R, class... Args, R (*pf)(Args...)>
struct il_ptr_fun<R (*)(Args...), pf>
{
  typedef R result_type;
  
  R operator()( Args... args ) const {
    return (*pf)( std::forward<Args>(args)... );
  }
};

// 関数への参照、メンバ関数ポインタ等も同様に定義できるが今回は略

inline int square(int n){ return n * n; }

#include <iostream>

template<class F>
inline void print_ptr_fun(F f, int n)
{
  std::cout << f(n) << std::endl;
}

int main()
{
  print_ptr_fun( il_ptr_fun<int (*)(int), &square>(), 1 );
}

解答2

ラムダ式を使う。

inline int square(int n){ return n * n; }

#include <iostream>

template<class F>
inline void print_ptr_fun(F f, int n)
{
  std::cout << f(n) << std::endl;
}

int main()
{
  print_ptr_fun( [](int n){ return square(n); }, 1 );
}


後者のほうがずっと楽なので、後者で。

追記 (2012/03/01 26:00)

なお,これらの関数オブジェクトですが(ラムダは歴とした関数オブジェクトです),
もちろん C++03 版の il_ptr_fn に比べてオーバーヘッドはありません.
特にラムダは,それに相当する関数オブジェクトを自前で用意した場合と,原則として同じコードになります.
安心して C++11 の機能を お使いください.