次のように、テンプレート引数として関数ポインタを使用できます
template<class R, class T, R (*Fun)(T)>
class MyClass;
それを作るための任意の方法は次のように簡単です
MyClass<&MyFun> a;
次のように、テンプレート引数として関数ポインタを使用できます
template<class R, class T, R (*Fun)(T)>
class MyClass;
それを作るための任意の方法は次のように簡単です
MyClass<&MyFun> a;
これは恐ろしい答えですが、より良い答えは思いつきません。
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
を繰り返さずに抽出します...
質問とまったく同じようにはできませんが、デザインを少し変更すれば可能です。例を見てみましょう:
以下の関数があるとします:
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;
これが実際のデモです。
すでにありstd::ptr_fun
ます。C++11 では、次のように使用できます。
auto a = std::ptr_fun(&MyFun);
更新:
ところで、他の試みとそうでない試みが示したように、あなたの種類のテンプレートでは、少なくとも「同じくらい簡単に」それは可能ではありません;-)。ただし、主な目標が「同じくらい簡単」である場合は、既存の標準テンプレート関数パターン (std::ptr_fun
など) を再実装して目的の型を返すことができます。std::make_pair