construct
First, we need a base definition for make<T>
:
template <class T> struct make
{
outcome::result<T> operator()() const noexcept
{ //
static_assert(!std::is_same<T, T>::value, //
"make<T>() was not specialised for the type T supplied");
}
};
This fails a static assert if the type is ever instantiated unspecialised.
We then specialise for make<file_handle>
:
template <> struct make<file_handle>
{
file_handle::path_type _path;
file_handle::mode _mode{file_handle::mode::read};
// Any other args, default initialised if necessary, follow here ...
outcome::result<file_handle> operator()() const noexcept //
{
return file_handle::file(std::move(_path));
}
};
Because this is a struct, we can list initialise make
, and use
default member initialisers to implement default arguments. This can get
you surprisingly far before you need to start writing custom constructors.
But in more complex code, you will usually provide all the initialisation overloads that
you would for the constructors of your main type. You then implement a single phase 2 constructing
function which accepts make<YOURTYPE>
as input, and construct solely from
that source.