std::string has a constructor that takes an initializer_list argument.
basic_string( std::initializer_list<CharT> init, const Allocator& alloc = Allocator() );
This constructor always takes precedence when you use a list with an initialization binding to build std::string . Other constructors are only considered if elements in parentheses-init-list are not converted to the element type in initializer_list . This is mentioned in [over.match.list] / 1 .
Initially, candidate functions are initializer constructors ([dcl.init.list]) of class T , and the argument list consists of a list of initializers as one argument.
In your example, the first argument 5 implicitly converted to char , so the initializer_list constructor is viable and is selectable.
This is obvious if you print each character in lines as int s
void print(char const *prefix, string& s) { cout << prefix << s << ", size " << s.size() << ": "; for(int c : s) cout << c << ' '; cout << '\n'; } string str1 {"aaaaa"}; string str2 {5, 'a'}; string str3 (5, 'a'); print("str1: ", str1); print("str2: ", str2); print("str3: ", str3);
Output:
str1: aaaaa, size 5: 97 97 97 97 97 str2: a, size 2: 5 97 str3: aaaaa, size 5: 97 97 97 97 97
demo version
source share