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.

Reply via email to