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 = construct<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 construct<file_handle> using the arguments with which we wish to invoke the file_handle constructor with, and then invoking the call operator on that construct<file_handle> instance to do the actual construction.

We think that this is a better approach than alternatives, but we shall briefly cover those at the end of this section.