# Phase 3

We have built our first two phases of construction for `file_handle`, and for some users they might be happy writing:

      outcome::result<file_handle> fh1 = file_handle::file("hello" /*, file_handle::mode::read */);
      if(!fh1)
      {
        std::cerr << "Opening file 'hello' failed with " << fh1.error().message() << std::endl;
      }

View this code on Github

… and be done with it.

But wouldn’t it be nicer if we could instead write:

      outcome::result<file_handle> fh2 = make<file_handle>{"hello" /*, file_handle::mode::read */}();
      if(!fh2)
      {
        std::cerr << "Opening file 'hello' failed with " << fh2.error().message() << std::endl;
      }

View this code on Github

The eye is immediately drawn to the two-stage invocation pattern, so we are constructing a type `make<file_handle>` using the arguments with which we wish to invoke the `file_handle` constructor with, and then invoking the call operator on that `make<file_handle>` instance to do the actual construction.

It may seem a bit clunky to use brace initialisation for parameters followed by a “spurious” set of empty brackets, but we think that this is a better approach than alternatives. We shall briefly cover those at the end of this section.

Last revised: February 08, 2019 at 22:18:08 UTC