https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105838
--- Comment #14 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jason Merrill from comment #12)
> Another significant part of the problem is that vector<string> doesn't have
> a generic initializer_list constructor. Adding
>
> template <typename __elt>
> _GLIBCXX20_CONSTEXPR
> vector(initializer_list<__elt> __l,
> const allocator_type& __a = allocator_type())
> : _Base(__a)
> {
> _M_range_initialize(__l.begin(), __l.end(),
> random_access_iterator_tag());
> }
>
> so that it can construct from initializer_list<const char *> makes the
> construction into a simple loop over a static array.
Which is potentially *much* more efficient, because it constructs the strings
in place, instead of making unelidable copies of the initializer_list elements.
> Jonathan, has anyone suggested adding generic init_list constructors to the
> container classes?
Not that I'm aware of. There might be concerns about introducing more
ambiguities like the vector<int>{1,2} case.
> What do you think about doing the above translation in the compiler? Is the
> compiler allowed to do that?
Good question.
If the compiler first checked that the code as-written would call the
initializer_list<value_type> constructor (and not some other constructor) then
it should be safe to do it.
In the general case, somebody would probably find a way to notice and complain.
But if you're thinking of optimizing the specific case of vector<string> then I
think it would be unobservable. The string copies can't be observed, because
it's unspecified when and how often std::allocator calls operator new.