次のコードがあるとします。
#include <iostream>
#include <functional>
template <int func(int)>
struct S : std::unary_function<int, int>
{
int operator()(int x) const
{
return func(x);
}
};
int foo(int x)
{
return x;
}
int main()
{
S<foo> s;
std::cout << s(42) << std::endl;
}
これは、関数をファンクター内にラップする方法として問題なく機能します。つまり、他のテンプレート化された関数で使用できることを意味します (sort
たとえば、(ファンクターが正しいシグネチャを持っていると仮定して))。可能なすべての戻り値/引数の型に対してファンクター構造体を作成したくない (現実的にはできません) ため、次のことを試しました。
template <template <typename R, // Make the return type and argument type template parameters!
typename A> R func(A)>
struct S : std::unary_function<R, A>
{
R operator()(A arg) const
{
return func(arg);
}
};
それはうまくいきませんでした。コンパイルエラーが発生しました。それで、私は試しました:
template <typename R, typename A, R func(A)>
struct S : std::unary_function<R, A>
{
R operator()(A arg) const
{
return func(arg);
}
};
これはうまくいきました。残念ながら、のインスタンス化をより良いものではなく変更するS
必要がありました。S<int, int, foo> s;
S<foo> s;
S<foo> s;
で関数の戻り値の型と引数の型をハードコーディングしないように、テンプレート引数として渡された関数をテンプレート化することはまったく可能S
ですか?
私の google-foo は特定の答えを見つけることができませんでした。
編集:今、これが不可能かどうか疑問に思っています。foo
「オーバーロードされた関数はどうなるの?」と思っただけです。私の知る限り、戻り値/引数の型を明示的に述べるときにどちら foo
を使用するかを知る方法はありません。これは正しい考えでしょうか? これは、私の最初の質問に対する答えが「いいえ、不可能です」ということですか?S<foo> s;