'Is there an alternative to the builder pattern that is preferred in C++?
I'm coming from Java where the builder pattern is used heavily, e.g.
Foo foo = new FooBuilder()
.setBar(43)
.setBaz("hello, world!")
.enableCache(true)
.build();
Automapper for example is popular library that generates this pattern via Java annotations.
I don't see any such library for C++—only gists and blog posts online with example ad hoc implementations.
Does the lack of a library imply that the builder pattern is not preferred in C++? What is the alternative or preferred idiom then?
Maybe it helps to describe what I actually want. I like the grammar that the builder pattern affords me, for example if there are 20 fields I could set (e.g. a large configuration), but may only set 4 or may set all 20, without having to create explicit constructors for each case.
Solution 1:[1]
A common pattern is aggregate initialisation:
Foo foo = {
.bar=43,
.baz="hello, world!",
.enableCache=true,
};
Note that designated initialisers such as used here were introduced in C++20. Prior to that, you could only initialise sub objects positionally.
Another pattern, common in absence of designated initialisers, is value initialisation followed by assignment of data members:
Foo foo = {};
foo.bar = 43;
foo.baz = "hello, world!";
foo.enableCache = true;
Usage of neither pattern requires the use of a library.
Solution 2:[2]
If it's your code, you can approximate it by having your settings return *this as follows:
class Foo {
public:
Foo & setter1(int value) { ...; return *this; }
Foo & setter2(int value) { ...; return *this; }
};
Foo foo;
foo.setter1(1)
.setter2(2);
Or pointers or smart pointers, or whatever. I've taken to doing this because it makes for slightly cleaner code. Clearly, if your constructor does a lot, you're still doing a lot. You also have a problem if Foo is a subclass, and some of your setter calls are on the base class, because suddenly you don't have a Foo being returned, but a BaseFoo.
So it's not perfect.
I've seen self-implemented builder patterns that actually are a proper builder, but frankly, I think that's a lot of overhead with zero gain.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Joseph Larson |
