2016-09-05 11 views
-1

複数のコンストラクタを持つファンクタを作成することはできますか?私は様々な方法でファンクタを使用できるようにしたい。さまざまなメンバをさまざまな方法で初期化する。これらのメンバは、初期にどのコンストラクタを設定するかによって異なる。複数のコンストラクタを持つC++(C++ 98)ファンクタ?

しかし、複数のコンストラクタを持つファンクタを使用してここで提案するよりも洗練されたソリューションがありますか?

このレベルの再利用は、私が書いている通信ワイヤプロトコルインタープリタで非常にうまくいくでしょう。通信回線の特定のワイヤ(またはワイヤのサブセット)は、使用される特定のプロトコルに応じて、異なる目的を果たすことがあります。したがって、それぞれが比較的適応性の低い非常に特殊なファンクタの大きなセットを作成するのではなく、妥当なパラメータ内で適応可能な小さなファクタのセットを作成できるようにしたいと考えています。

次に、クラス内で具体化された「ルール」に従ってデータを読み書きすることができる、別のクラスのテンプレート関数のパラメータとして、一度に1つずつ、より小さい順応性の高いファンクタが使用されますテンプレート関数を呼び出すために使用されるファンクタパラメータ。

私の目的は、プロトコルとサブプロトコルのさまざまな順列を同じ基本コードで使用できるように、コードを可能な限り一般的なものにすることです。

+3

答えは「はい」ですが、実際の質問には答えられないようです。本当の質問は何ですか? – nwp

+0

ファンクタは基本的にoperator()()を持つ構造体です –

+2

C++ 99のようなものはありません。おそらく98を意味するでしょうか? –

答えて

0

ご質問がわかりません。ストレートな答えです:はい、あなたは演算子をオーバーロードすることもできます()。

class MyFunctor { 
public: 
    MyFunctor(int a) : a(a), b(0.0) {} 
    MyFunctor(double b) : a(0), b(b) {} 

    int operator()(int c) const { return a + c; } 
    double operator()(double c) const { return b + c; } 
private: 
    int a; 
    double b; 
}; 

MyFunctor fromInt(2); 
MyFunctor fromDouble(2.1); 

std::cout << fromInt(3) << std::endl; // Print 5 
std::cout << fromInt(3.1) << std::endl; // Print 3.1 

std::cout << fromDouble(2) << std::endl; // Print 2 
std::cout << fromDouble(2.2) << std::endl; // Print 4.3 

ただし、これはSingle responsibility principleに違反していると感じています。より良い解決法は、いくつかの小さなファンクタを作成し、ファクトリを使用して最適なものを選択することです。

class MyFunctorInt { 
public: 
    MyFunctorInt(int a) : a(a) {} 
    int operator()(int c) const { return a + c; } 
private: 
    int a; 
}; 
class MyFunctorDouble { 
public: 
    MyFunctorDouble(double b) : b(b) {} 
    double operator()(double c) const { return b + c; } 
private: 
    double b; 
}; 

MyFunctorInt createFunctor(int a) 
{ return MyFunctorInt(a); } 
MyFunctorDouble createFunctor(double b) 
{ return MyFunctorDouble(b); } 

template<class Callable, class Real> 
void myGenericFunction(const Callable &f, Real a) 
{ std::cout << f(a) << std::endl; } 

myGenericFunction(createFunctor(2),3); // Print 5 
myGenericFunction(createFunctor(2.2),3); // Print 5.2 

これは、コードに新しい機能を追加したい場合など、これはおそらく改善されます。文字列の場合は、新しいクラスMyFunctorStringと新しいオーバーロードcreateFunctor(std :: string)がある新しいファイルを作成することができます。この新しいクラスを簡単に単体テストできます。さまざまなオーバーロード間のやりとりを心配する必要はありません。たとえば、最初にMyFunctorのコードを書いたとき、すべてのメンバーを0に初期化するのを忘れて、定義されていない結果が得られました。

+0

kevin->いくつかの小さなファンクタを使用する工場でのアプローチは非常に興味深い解決策です!私のニーズ、詳細、それぞれの状況でどのファンクタを使用するかを選択する仕組みをカバーするために、ファンクタのコレクションを作成する必要がありますが、かなりうまくカプセル化され、隠されているので、いいです。あなたが言うように、それは非常に維持可能であり、強力です。本当に素晴らしい!私はこれを試してみましょう。私は結果と質問であなたに戻ってきます。 – user2680840

関連する問題