I have a class that looks like the following:
class Example {
Foo1 f1;
Foo2 f2;
Foo3 f3;
size_t hash;
};
Please note that FooX will be always different classes. I want to add a constructor which assigns the value to each fX element and computes the hash (for cacheing its value).
However I want to be able to omit any number of arguments and assign a default value to the corresponding member of the class. Obviously I could use the defaulting feature of C++:
Example(Foo1 f1 = DEFAULT4F1, Foo2 f2 = DEFAULT4F2, Foo3 f3 = DEFAULT4F3);
However for being able to omit f2, I need to omit f3, which I might want to specify. Then I could write a constructor for each possible order, but the amount of constructors grows with the factorial of elements, so for this case:
Example(Foo1 f1 = DEFAULT4F1, Foo2 f2 = DEFAULT4F2, Foo3 f3 = DEFAULT4F3);
Example(Foo1 f1 = DEFAULT4F1, Foo3 f3 = DEFAULT4F3, Foo2 f2 = DEFAULT4F2);
Example(Foo2 f2 = DEFAULT4F2, Foo1 f1 = DEFAULT4F1, Foo3 f3 = DEFAULT4F3);
Example(Foo2 f2 = DEFAULT4F2, Foo3 f3 = DEFAULT4F3, Foo1 f1 = DEFAULT4F1);
Example(Foo3 f3 = DEFAULT4F3, Foo1 f1 = DEFAULT4F1, Foo2 f2 = DEFAULT4F2);
Example(Foo3 f3 = DEFAULT4F3, Foo2 f2 = DEFAULT4F2, Foo1 f1 = DEFAULT4F1);
I don't want to specify the same constructor that many cases, because in my real case there are more than 3 parameters. I also want to consider forwarding their values (Foo&& arg
and std::forward(arg)
)
Edit: To sum up: desired constructor would act like this, but being able to omit any of the parameters, and use a default value for them
Example(Foo1&& f1, Foo2&& f2, Foo3&& f3) :
f1(std::forward(f1)),
f2(std::forward(f2)),
f3(std::forward(f3)),
hash(doSomethingForIt())
{
}
This is a workaround, not an initialization in C++ sense.
Because you need in advance all members of your class, you already know them:
class Example {
Foo1 f1;
Foo2 f2;
Foo3 f3;
size_t hash;
//default ctor, initializes all members with defaults defined somewhere
Example() : f1(defaultF1), f2(defaultF2), f3(defaultF3) {}
....
Now we add setters:
Example& setFoo1(Foo1 fo1 = defaultF1)
{
f1 = fo1;
return *this;
}
Example& setFoo2(Foo2 fo2 = defaultF2)
{
f2 = fo2;
return *this;
}
....
}; //class Example
And then the usage:
Example exple;
exple.setFoo2(someF2value).setFoo1(someF1value); //not all setFooX are used
Notice that we can call setFooX() in any order.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With