Yes.
The map's element initialisation will be via default constructor.
And, per my previous answer on the subject, this honours your default initializer.
[unord.map.elem]:
mapped_type& operator[](const key_type& k);
1/ Effects: Equivalent to: return try_emplace(k).first->second;
[unord.map]:
template<class... Args> pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
6/ Effects: If the map already contains an element whose key is equivalent to k
, there is no effect. Otherwise inserts an object of type value_type
constructed with piecewise_construct, forward_as_tuple(k), forward_as_tuple(std::forward<Args>(args)...)
.
[pairs]:
template<class... Args1, class... Args2> constexpr pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args);
/15: Effects: Initializes first
with arguments of types Args1...
obtained by forwarding the elements of first_args
and initializes second
with arguments of types Args2...
obtained by forwarding the elements of second_args
. (Here, forwarding an element x
of type U
within a tuple
object means calling std::forward<U>(x)
.) This form of construction, whereby constructor arguments for first
and second
are each provided in a separate tuple object, is called piecewise construction.
(recall that Args2...
is empty here, so no constructor arguments are provided to Foo
, but the mechanism is still that as for constructor usage)