Another common use is for parameter objects. Without a chain of methods, they are quite inconvenient to configure, but with them they can be temporary.
Instead:
complicated_function(P1 param1 = default1, P2 param2 = default2, P3 param3 = default3);
Record:
struct ComplicatedParams { P1 mparam1; P2 mparam2; P3 mparam3; ComplicatedParams() : mparam1(default1), mparam2(default2), mparam3(default3) {} ComplicatedParams ¶m1(P1 p) { mparam1 = p; return *this; } ComplicatedParams ¶m2(P2 p) { mparam2 = p; return *this; } ComplicatedParams ¶m3(P3 p) { mparam3 = p; return *this; } }; complicated_function(const ComplicatedParams ¶ms);
Now I can call it:
complicated_function(ComplicatedParams().param2(foo).param1(bar));
This means that the caller does not need to remember the order of the parameters. Without a chain of methods, which should be:
ComplicatedParams params; params.param1(foo); params.param2(bar); complicated_function(params);
I can also call it:
complicated_function(ComplicatedParams().param3(baz));
This means that without defining a ton of overloads, I can specify only the last parameter and leave the rest by default.
The final obvious setup is to make complicated_function member of ComplicatedParams :
struct ComplicatedAction { P1 mparam1; P2 mparam2; P3 mparam3; ComplicatedAction() : mparam1(default1), mparam2(default2), mparam3(default3) {} ComplicatedAction ¶m1(P1 p) { mparam1 = p; return *this; } ComplicatedAction ¶m2(P2 p) { mparam2 = p; return *this; } ComplicatedAction ¶m3(P3 p) { mparam3 = p; return *this; } run(void); }; ComplicatedAction().param3(baz).run();
Steve jessop
source share