2017-09-20 10 views
0

私は4つまでの引数を取る関数を持っています。それらはすべてオプションです。また、すべての引数はデフォルト値を持ち、ユーザーは必要な引数の組み合わせを指定できます。私はこれがあればC++:デフォルトパラメータの組み合わせ

ので:

void func (const A &a = A(), const B &b = B(), const C &c = C(), const D &d = D()); 

をユーザーがfunc(A(), B())としてではなく、func(B(), C())として使用することができます。

複数のオーバーロードを作成せずにすべての引数の組み合わせを許可する方法はありますか? (この場合は8となるでしょう)

+1

名前付きパラメータイディオム(ビルダーパターンとも呼ばれます)、構造体(特にC++では指定されたイニシャライザを使用します)、[ブーストパラメータ](http://www.boost.org/doc/libs/1_65_1/libs/parameter /doc/html/index.html)(またはそれに類するライブラリ) – Justin

+0

私はそれが今あるとは思わないが、 'va_arg'は同様の機能を許しているが、私は全く同じではないと確信している。 http://www.cplusplus.com/reference/cstdarg/va_arg/ –

+2

これはたくさん聞かれますが、実際には実際の実例を尋ねたことはほとんどありません。多分あなたは違うかもしれません。その場合、あなたの問題とデザインの詳細を投稿してください。 –

答えて

0

私は大きなコードベースと古いコードベースを扱っているときに特にこのような問題が発生しています。最善の解決策は、あなたがそのような問題に終わらないように物事を再設計することですが、時にはあなたが圧迫されており、最小限の変更で行う必要があることを理解しています。

このようなことについては、その関数のパラメータをカプセル化するクラスを作成することをお勧めします。あなたが渡すパラメータする柔軟性を持っているであろうとそう

https://en.wikipedia.org/wiki/Builder_pattern

:そして、そのクラスは、Builderのデザインパターンを持っているでしょう。あなたはこのようなものかもしれないあなたが与えた例では

、:

void func(FuncParams *params); 

そして、あなたはこのようにそれを呼び出すことができます:次に

class FuncParams 
{ 
    public: 
    A& getA(); 
    B& getB(); 
    C& getC(); 
    D& getD(); 

    class FuncParamsBuilder 
    { 
     FuncParamsBuilder& setA(A& a); 
     FuncParamsBuilder& setB(B& b); 
     FuncParamsBuilder& setC(C& c); 
     FuncParamsBuilder& setD(D& d); 
     FuncParams *build(); 
    } 

    static FuncParamsBuilder& builder(); 
} 

を、あなたの関数呼び出しがちょうどだろう

func(FuncParams::builder().setA(a).setC(c).build()); 

これはこれをコード化する完全な方法ではないことに注意してください。上記のコードスニペットを変更する必要がありますあなたがやろうとしていることをより良く合うために。ポインター、参照、さらにはunique_ptrオブジェクトなどのスマートポインターを使用したいと考えるかもしれません。私はこれが助けて欲しい!

+0

'func(a、B {}、c);'は入力がずっと少なく、元の関数を使うことができます。 –

+0

これは絶対に当てはまります。しかし、私はこの練習のポイントは、パラメータに値を渡さないことだと思っていました。値をパラメータに渡すと、デフォルト値は必要ありません。常に値を渡すことができます。 – Discoverer98