Is this oversight in the standard?
It is considered an open defect in the standard, tracked as LWG # 2089 . But a good solution to this is elusive.
The main problem arises from the fact that you cannot just use bit-init lists perforce. Type initialization lists with constructors can actually hide constructors, so some constructors may not be possible to call through list initialization. This is a problem vector<int> v{1, 2}; . This creates a 2-element vector , not a 1-element vector, the only element of which is 2.
Because of this, you cannot use list initialization in general contexts, such as allocator::construct .
Which brings us to:
I would think that if possible, there is a SFINAE trick, otherwise resort to init, which also works for aggregates.
This will require a type of type is_aggregate . Which does not exist at present, and no one has proposed its existence. Of course, you could agree with is_constructible , as the proposed resolution states to this question. But there is a problem with this: it effectively creates an alternative to initializing lists.
Consider the vector<int> example from the previous one. {1, 2} interpreted as a two-element initializer_list . But through emplace it will be interpreted as a call to a dual-purpose constructor, since the is_constructible of these two elements will be true. And this causes this problem:
vector<vector<float>> fvec; fvec.emplace(1.0f, 2.0f); vector<vector<int>> ivec; ivec.emplace(1, 2);
They do two completely different things. In the case of fvec it initializes the list, because vector<float> not a constructive of two floats. In the case of ivec it calls the constructor, because vector<int> is a construct of two integers.
Therefore, you need to restrict the initialization of the list in allocator::construct only work if T is an aggregate.
And even if you did, you would have to distribute this SFINAE trick in all places where indirect initialization is used. This includes the constructors and replacements of any/variant/optional in_place , calls to make_shared/unique , etc., None of which use allocator::construct .
And this does not take into account user code where such indirect initialization is necessary. If users do not perform the same initialization as the standard C ++ library, people will be upset.
This is a key problem to solve in such a way as not to fork indirect initialization APIs into groups that do not allow aggregates and groups that do not. There are many possible solutions , and none of them are perfect.