'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