2017-09-20 53 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

命名参数idiom(aka Builder模式),结构(特别是在C++ 20中有指定的初始值设定项),[Boost参数](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

所以,你将不得不灵活哪些参数会通过。

在你给的例子,你可以有这样的事情:

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(); 
} 

然后,你的函数调用将只是:

void func(FuncParams *params); 

而且你可以这样调用它:

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

请注意,这不是一种完美的编码方式:您应该修改上面的代码片段以更好地适应你想要做的事情。你也可以考虑如果你想使用指针,引用或更好的智能指针,比如unique_ptr对象。我希望这有帮助!

+0

不禁要指出'func(a,B {},c);'键入的次数少得多,可以使用原始函数。 –

+0

这绝对是真的。但是,我认为这个练习的重点是*不*将值传递给参数。如果我们将值传递给参数,那么我们甚至不需要默认值:我们可以一直传递值。 – Discoverer98