Copy List Initialization? Why does this compile?

That use the constructor with iterators of std::string (6.).

template< class InputIt >
constexpr basic_string( InputIt first, InputIt last,
                        const Allocator& alloc = Allocator() );

With [InputIt = const char*].

Then you have UB as the range {"str1", "str2"} is invalid.


std::string has a constructor overload in the form of

template< class InputIt >
basic_string( InputIt first, InputIt last,
              const Allocator& alloc = Allocator() );

and this gets called because "str1" and "str2" decay to const char*'s and const char* is an acceptable iterator type.

You get a crash because the "iterator range" you passed to the function is invalid.


std::string has a template constructor that builds a string from a begin/end iterator pair. String literals in C++ devolve down to const char*s. And pointers are iterators. Therefore, list initialization picked the begin/end pair constructor.

You got a runtime error because the two pointers do not actually create a valid range, which cannot be determined at compile-time (generally).

Tags:

C++