I was reading c++ primer and came across an example of list initialization for vector where the author mentioned that if list initialization isn't possible, the compiler then looks for other ways to initialize the object. Below is such an example for vector of string.
vector<string> v8{10, "hi"};
This creates a vector of 10 elements with value "hi". This I think is because list initialization falls back on below constructor to create the vector.
vector( size_type count, const T& value, const Allocator& alloc = Allocator());
I tried similar kind of list initialization for String
std::string s1{10, 'c'};
I was expecting it to create a string "cccccccccc" because there is a constructor available for it
basic_string( size_type count, CharT ch, const Allocator& alloc = Allocator() );
But it prints only "c"? Which string constructor is getting used here?
What's coming into play here are the rules for
direct-list-initialization
which has one of the syntax asHere, in the case of
std::string s{10, 'c'}
,T
in the above syntax isstd::string
and the rule that applies isSince there is a constructor of
std::string
that takes in an initializer list with the other arguments as default, namely constructor (9)that participates in this resolution since
10
can be implicitly converted tochar
and what you get is astd::initializer_list<char>
of{'\n', 'c'}
of 2 characters.In the case of
std::vector<std::string> v{10. "hi"}
,T
isstd::vector<std::string>
in the syntax fordirect-list-initialization
as mentioned above.Now, since
10
can't be implicitly converted tostd::string
, no suchstd::initializer_list<std::string>
can be constructed and thus the next alternative fordirect-list-initialization
isThis produces a match with constructor 3
since neither of the conversions is non-narrowing.
Now coming to what you wanted to achieve with
std::string s{10, 'c'}
, that should be done usingstd::string s(10, c)
where there is nolist-initialization
involved.Output:
Note that printing
s1
produces a new line before thec
since it's actually['\n', 'c']
, whereass2
is exactly what you'd expect i.e. 10c
characters.