A(3)
経由数子を呼び出すために、そしてA
は変数、ないタイプの名前にする必要があります。これは、Aがファンクタのインスタンスでなければならないことを意味します。ファンクタのタイプが公開されているため複雑になります。その場合、他の人が構築やコピー、アドレス指定などを禁じる必要があります。あるいは、Aを通常の関数にする。
functors.h
int A(int x);
functors.cpp
struct AFunctor {
int operator()(int x) const {return 3*x;} ;
};
int A(int x) {
static AFunctor a;
return a(x);
}
main.cppに
#include "functors.h"
int main()
{cout << A(3) << endl;}
この時点では明らかである、シングルトンを持ってする理由は、文字通りありません通りこのようなファンクタ。 Functorは通常はステートフルであり、左右に作成することも、その両方を行うこともできます。
シングルトン・ファンクタを間違いなく使用していることが明らかになったので、これは私が推測する方法です。
functors.h
struct activation
{
virtual float operator() (float x) const = 0;
virtual float gradient (float x, float g) const = 0;
};
struct sigmoidFunctor : activation
{
float operator() (float x);
float gradient(float x, float g);
static sigmoidFunctor& get();
private
sigmoidFunctor()=default;
sigmoidFunctor(const sigmoidFunctor&)=delete;
};
extern sigmoidFunctor& sigmoid;
struct reluFunctor : activation
{
float operator() (float x);
float gradient(float x, float g);
static reluFunctor& get();
private
reluFunctor()=default;
reluFunctor(const reluFunctor&)=delete;
};
extern reluFunctor& relu;
複雑で広大な増加によって証明されるようにfunctors.cpp
float sigmoidFunctor::operator() (float x)
{ return 1.f/(1.f + expf(-x)); }
float sigmoidFunctor::gradient(float x, float g)
{ float s = (*this)(x); return g * s * (1.f - s); }
sigmoidFunctor& sigmoidFunctor::get() {
static sigmoidFunctor sigmoid;
return sigmoid;
}
sigmoidFunctor& sigmoid = sigmoidFunctor.get();
float reluFunctor::operator() (float x)
{ return x; }
float reluFunctor::gradient(float x, float g)
{ return g; }
reluFunctor& reluFunctorFunctor::get() {
static reluFunctor relu;
return relu;
}
reluFunctor& relu = reluFunctor.get();
は、私は強く再考するあなたを促します。通常、シングルトンはすべてを混乱させるだけです。
なぜ彼らはファンクタですか? –
スタイルとコードの読みやすさと一貫性のための詳細 – user2255757
この質問はファンクタオブジェクトのためだけではありませんが、一般的なインスタンス化の質問 – user2255757