Avoiding the boredom of optional options

If I have a constructor with 2 required parameters and 4 optional parameters, how can I avoid writing 16 constructors or even 10 or so constructors that I would have to write if I used the default parameters (which I don’t like because it poor self-documentation)? Are there any idioms or methods using patterns that I can use to make it less tedious? (And easier to maintain?)

+16
c ++ idioms constructor optional-parameters
Apr 23 '10 at 18:14
source share
4 answers

You may be interested in the Named Parameter Identifier .

To summarize, create a class that contains the values ​​you want to pass to your constructor (s). Add a method to set each of these values, and each of them will do return *this; in the end. You have a constructor in your class that references this new class. This can be used like this:

 class Person; class PersonOptions { friend class Person; string name_; int age_; char gender_; public: PersonOptions() : age_(0), gender_('U') {} PersonOptions& name(const string& n) { name_ = n; return *this; } PersonOptions& age(int a) { age_ = a; return *this; } PersonOptions& gender(char g) { gender_ = g; return *this; } }; class Person { string name_; int age_; char gender_; public: Person(const PersonOptions& opts) : name_(opts.name_), age_(opts.age_), gender_(opts.gender_) {} }; Person p = PersonOptions().name("George").age(57).gender('M'); 
+34
Apr 23 '10 at 18:19
source share

What if you created a parameter object containing all the fields? Then you can simply pass this on and just set any fields you need. This may be the name for this template, but not sure what it is ...

UPDATE:

The code might look something like this:

 paramObj.x=1; paramObj.y=2; paramObj.z=3; paramObj.magic=true; ... //set many other "parameters here" someObject myObject = new someObject(paramObj); 

and inside the someObject constructor someObject you can set default values ​​for things that have not yet been set (or cause an error if necessary).

Honestly, I'm not a big fan of this solution, but I used it once or twice when paramObj made sense, containing a set of data that usually came together (so that we could use it for more than just constructors), and it was better. than several designers. I found that it was ugly, but it worked, YMMV.

+9
Apr 23 '10 at 18:20
source share

And now for “Boost there is something for this” answer:

The Boost Parameter Library seems to be well-suited for your use.

+4
Apr 23 '10 at 18:52
source share

All new for C ++ 17

 #include <optional> using optional_int = std::optional<int>; class foo { int arg0, arg1; // required int arg2, arg3; // optional const int default_2 = -2; const int default_3 = -3; public: foo(int arg0, int arg1, optional_int opt0 = {}, optional_int opt1 = {}) : arg0(arg0), arg1(arg1) , arg2(opt0.value_or(default_2)) , arg3(opt1.value_or(default_3)) { } }; int main() { foo bar(42, 43, {}, 45); // Take default for opt0 (arg2) return 0; } 

I have a cubic spline implementation that allows the user to optionally indicate the first derivative either at the left end, and at the right end, or both. If the derivative is not specified, then the current code calculates one, assuming that the second derivative is zero (the so-called "natural spline"). Here is a snippet for the left end.

 // Calculate the second derivative at the left end point if (!left_deriv.has_value()) { ddy[0]=u[0]=0.0; // "Natural spline" } else { const real yP0 = left_deriv.value(); ddy[0] = -0.5; u[0]=(3.0/(x[1]-x[0]))*((y[1]-y[0])/(x[1]-x[0])-yP0); } 
+1
Jan 20 '18 at 6:01
source share



All Articles