Builder pattern that forces all members to be initialized at compile-time This java answer made me wonder whether it would be possible to implement the builder pattern in C++ in a way that checks at compile-time whether all necessary members of the constructed object are actually set before the object is constructed. This is what I came up with:

struct Foo {
    int x_;
    int y_;
    int z_;
};

template &lt;bool x_set = 0, bool y_set = 0, bool z_set = 0&gt;
struct FooBuilder {
    int x_, y_, z_;

    Foo build() {
        static_assert(x_set &amp;&amp; y_set &amp;&amp; z_set, "all members must be initialized before building a Foo!");
        return { x_, y_, z_};
    }

    FooBuilder&lt;1,y_set,z_set&gt; x(int val) {
        FooBuilder&lt;1,y_set,z_set&gt; result;
        result.x_ = val;
        result.y_ = y_;
        result.z_ = z_;
        return result;
    }

    FooBuilder&lt;x_set,1,z_set&gt; y(int val) {
        FooBuilder&lt;x_set,1,z_set&gt; result;
        result.x_ = val;
        result.y_ = y_;
        result.z_ = z_;
        return result;
    }

    FooBuilder&lt;x_set,y_set,1&gt; z(int val) {
        FooBuilder&lt;x_set,y_set,1&gt; result;
        // optional check to allow z to be set only once
        static_assert(!z_set, "z may not be initialized twice!"); 
        result.x_ = val;
        result.y_ = y_;
        result.z_ = z_;
        return result;
    }
};

int main() {
    FooBuilder&lt;&gt; b;
    auto f1 = b.x(1).y(2).z(3).build();
    auto f1a = b.z(3).y(2).x(1).build();
    auto f2 = b.x(1).y(2).build(); // fails with static assertion 
    auto f3 = b.x(1).y(2).z(3).z(4).build(); // fails with static assertion 
    auto partially_initialized_builder = b.x(1);
    auto f4 = partially_initialized_builder.build(); // fails...
    auto f5 = partially_initialized_builder.y(4).z(6).build(); // runs

    return 0;
}


With this approach, I like the fact that programming errors that result from forgotten arguments to the builder can be caught at compile-time. However, I'm not sure if it is too verbose, since the whole content of the builder has to be copied/moved in each setter method (even if the copies might be optimized away). 

So my main questions are: 


Would such a pattern actually be useful in practice?
Is there an elegant way of sharing the member variables of the Builder objects, despite the results of each setter call being of a different type? (For cheap-to-move types, I am thinking along the lines of a "data block"-like struct, that gets moved from this into the result.)
Any other downsides to this approach?


P.S.: Please disregard the lack of access control (x_ etc. should be private), this question is more about the high-level picture ;-)
Would such a pattern actually be useful in practice?


Not really in my opinion. In C++20 you can use designated initializer lists like {.min = 10, .max = 20} and I mean if the argument is not clear from the context than there are various ways to improve this, even today.


A comment. Foo f(/*min=*/10);
User-defined literals Rectangle r(10_width, 200_height);
Strong types: Player p(Position(10, 10));
Variables: const int size = 10; Square s(size);


This also doesn't work with non-copyable, non-moveable types, although those are rare in practice. The members also need to be default constructible unfortunately.

Some thoughts:


Note that your code has undefined behavior, since two of the variables are not set on the first call.
The build function is required in Java, but in C++ you can use a conversion operator. Although this suffers from the same problem that expression templates have: Using type deduction will not get you a Foo.
Delete copy construction for the builder object, since there is no reason to copy it.
Don't use 0 and 1 for bools please; false and true is clearer IMO.
Consider using noexcept and constexpr (if applicable).



  Is there an elegant way of sharing the member variables of the Builder objects, despite the results of each setter call being of a different type? (For cheap-to-move types, I am thinking along the lines of a "data block"-like struct, that gets moved from this into the result.)


Yes that's a good idea. Here's my take on it:

template &lt;bool x_set = false, bool y_set = false, bool z_set = false&gt;
struct FooBuilder {
  constexpr FooBuilder() noexcept = default;
  FooBuilder(const FooBuilder &amp;) = delete;
  FooBuilder &amp;operator=(const FooBuilder &amp;) = delete;

  constexpr auto x(int val) noexcept {
    members_.x_ = val;
    return FooBuilder&lt;true, y_set, z_set&gt;(std::move(*this));
  }
  constexpr auto y(int val) noexcept {
    members_.y_ = val;
    return FooBuilder&lt;x_set, true, z_set&gt;(std::move(*this));
  }
  constexpr auto z(int val) noexcept {
    static_assert(!z_set, "cannot set z twice!");
    members_.z_ = val;
    return FooBuilder&lt;x_set, y_set, true&gt;(std::move(*this));
  }

  constexpr operator Foo() noexcept {
    static_assert(x_set &amp;&amp; y_set &amp;&amp; z_set, "all members must be set");
    return {members_.x_, members_.y_, members_.z_};
  }
  constexpr Foo build() noexcept { return *this; }

private:
  template &lt;bool... args&gt;
  constexpr FooBuilder(FooBuilder&lt;args...&gt; &amp;&amp;other) noexcept
      : members_{std::move(other.members_.x_), std::move(other.members_.y_),
                 std::move(other.members_.z_)} {}

  template &lt;bool, bool, bool&gt; friend struct FooBuilder;

  struct Proxy {
    int x_, y_, z_;
  } members_{};
};


There is still a lot of boilerplate, but unfortunately it cannot be removed since C++ doesn't have reflection yet.