C++ fluent builder pattern

Nicol Leung
2 min readApr 13, 2022

You may think fluent API is some fancy luxury ideas in Java / JavaScript, but in fact C++ can also achieve this in a clean and reliable way (without screwing with object scopes). Let’s see the following example of a toy HTML builder (don’t put it in production):

The builder usage is very clean isn’t it? But the question is why it works. The ctx.htmlBuilder() expression creates a temporary HTMLBuilder object, then we keep calling those builder functions which returns the reference of the builder itself. The key here is, the temporary builder object lives to the end of the statement, so that we can chain the function calls without worrying about dangling pointers.

All temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created, and if multiple temporary objects were created, they are destroyed in the order opposite to the order of creation. This is true even if that evaluation ends in throwing an exception.

There are two exceptions from that:

The lifetime of a temporary object may be extended by binding to a const lvalue reference or to an rvalue reference (since C++11), see reference initialization for details.

The lifetime of a temporary object created when evaluating the default arguments of a default or copy constructor used to initialize an element of an array ends before the next element of the array begins initialization.

We can log the order of ctor and dtor to verify this behavior:

MyContext()
HTMLBuilder(0)
Node(0)
TextNode(0)
Node(1)
TextNode(1)
~HTMLBuilder(0)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Welcome to C++ dev</title>
</head>
<body>
Hello World!
ni hao!
</body>
</html>
~MyContext()
~TextNode(0)
~Node(0)
~TextNode(1)
~Node(1)

Notice that ~HTMLBuilder() is called after constructors of TextNode.

That’s all for today! Welcome for comments~

--

--