The advantage of using unarchive here is that I can change the type of value_m without having to update this line of code - the type always follows the member variable's type.
One alternative is to create an alias for the type of value_m
and eliminate the decltype(value_m)
from the constructor initializer list:
struct foo
{
using value_type = int;
foo(const dictionary_t& archive, const key_type value_key) :
value_m(unarchive<value_type>(archive, value_key))
{ }
value_type value_m;
};
the unarchive<value_type>
still follows the type of value_m
. A static_assert
could be added to ensure the type of value_m
is the same as value_type
if there is concern of a change to the type of value_m
by not changing value_type
:
static_assert(std::is_same<decltype(value_m), value_type>::value,
"'value_m' type differs from 'value_type'");
or set the alias based on the type of value_m
:
int value_m;
using value_type = decltype(value_m);
If you still consider the constructor initialization list verbose provide a static
wrapper function that invokes the unarchive()
function:
struct foo
{
using value_type = int;
foo(const dictionary_t& archive, const key_type value_key) :
value_m(unarchive_(archive, value_key))
{ }
static value_type unarchive_(const dictionary_t& d, key_type k)
{
return unarchive<value_type>(d, k);
}
value_type value_m;
};
Having said all that:
value_m(unarchive<decltype(value_m)>(archive, value_key))
is not that verbose and precisely states the intention.