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;
}
… 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;
}
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.



