2

次のように、テンプレート引数として関数ポインタを使用できます

template<class R, class T, R (*Fun)(T)>
class MyClass;

それを作るための任意の方法は次のように簡単です

MyClass<&MyFun> a;
4

3 に答える 3

1

これは恐ろしい答えですが、より良い答えは思いつきません。

template<typename R, typename Arg, R(*Fun)(Arg)>
class MyClass {};

template<typename R, typename Arg>
struct MyClassHelper {
  template<R(*Fun)(Arg)>
  struct Class {
    typedef MyClass<R, Arg, Fun> type;
  };
};

template<typename R, typename Arg>
MyClassHelper<R, Arg> GetMyClass(R(*Fun)(Arg)); // no impl

void MyFun(int) {}

int main() {
  typedef decltype( GetMyClass(&MyFun) ) A;
  typedef A::Class<&MyFun> B;
  typedef B::type a;
  // or, in one line:
  decltype( GetMyClass(&MyFun) )::Class<&MyFun>::type b;
}

それは罪のように醜い。しかし、少なくとも、引数の型MyFunを繰り返さずに抽出します...

于 2013-01-01T19:22:41.637 に答える
0

質問とまったく同じようにはできませんが、デザインを少し変更すれば可能です。例を見てみましょう:
以下の関数があるとします:

int foo (int i) { return i; }

今、あなたは書きたい:

MyClass<&foo> a; // instead of `Myclass<int, int, &foo> a;

ここでは、それをどのように達成するかを説明します。最初に単純な関数を変更します。

int foo (int i) { return i; }

カプセル化された関数オブジェクトへ:

struct foo { // <--- function name here
  int operator () (int i) { return i; } // <--- function body here
};

両方ともほぼ同じです (関数オブジェクトの場合this、フリー関数の場合には発生しない追加のポインターが渡されます)。

int x = foo(2); // 1st case
int x = foo_(2); // 2nd case where `foo_` is an object of `struct foo`

思いのままに簡単に使えるようになりました!

template<class Func>
class MyClass {...}
MyClass<foo> a;

これが実際のデモです。

于 2013-01-01T19:38:56.613 に答える
-1

すでにありstd::ptr_funます。C++11 では、次のように使用できます。

auto a = std::ptr_fun(&MyFun);

更新

ところで、他の試みとそうでない試みが示したように、あなたの種類のテンプレートでは、少なくとも「同じくらい簡単に」それは可能ではありません;-)。ただし、主な目標が「同じくらい簡単」である場合は、既存の標準テンプレート関数パターン (std::ptr_funなど) を再実装して目的の型を返すことができます。std::make_pair

于 2013-01-01T17:38:10.593 に答える