C++
(関数オブジェクト) クラス (バリアディック) テンプレートを介して関数ラッパーを実装しようとしています。このクラスは、唯一のデータ メンバとして、ラップしている関数ポインタによって初期化されるか割り当てられた関数ポインタを持っています。パラメーター化されたコンストラクターは、関数ポインターを受け取り、それによってメンバーを初期化します。operator()メソッドは引数を取り (またはなし)、ラップされた関数を呼び出します。少なくともそれがアイデアです。多くのエラーが発生するので、コメントでマークします。VC11 (2012 年 11 月の CTP で、可変個引数テンプレートを有効にする) はerror C2091: function returns function、マークされた領域の 1 つを除くすべてで私を与えてくれます。最後のエラーは異なります。コード内でその完全な説明をコメントします。g++ では、コード番号が異なりますが、ほとんど同じエラーが発生します。
#include <iostream>
template <typename R, typename... Tn>
class func
{
R (*fptr)(Tn...); // C2091
public:
func() : fptr(nullptr) {}
func( R (*f) (Tn...) ) : fptr(f) {} // C2091
R operator()(Tn... args)
{ // C2091
return fptr(args...);
}
func& operator=( R (*f) (Tn...) ) // C2091
{
fptr = f;
return *this;
}
};
int foo(int a, int b)
{
std::cout << "foo\n";
return 0;
}
int main()
{
func<int(int, int)> myfunc;
myfunc = foo; // C2679: binary '=' : no operator found which takes
// a right-hand operand of type 'int (__cdecl *)(int,int)' (or
// there is no acceptable conversion)
}
これらのエラーが発生するのはなぜですか? たとえば、パラメーター化されたコンストラクターが何かを返す方法や、データ メンバーの宣言が何かを返す方法がわかりません。データメンバ宣言が関数ポインタ宣言になっていませんか? たとえば、を受け取って?を返すint (*g)(int);関数を指すポインターを宣言しません。intint
編集/補遺:
答えからわかるのは、それint(int, int)は 1 つのタイプのみであり、目的の効果を得るには部分的な特殊化が必要であるということです。しかし、私のコードでエラーが発生するのは何ですか? コメントアウトしてmyfunc = fooも、他のエラーが発生します。func<int(int, int)> myfunc;デフォルトのコンストラクターを呼び出します。typename Rにインスタンス化されint(int, int)、typename... Tn空になります。データ メンバは にR (*fptr)(Tn...);なるためR (*fptr)();、fptr引数を 0 とって を返す関数を指す関数ポインタになりますR。Rがint(int, int)の場合R、関数ポインタ型ですか、それとも関数型ですか? 後者の場合、エラー メッセージのコンテキストを理解できます。