lundi 28 août 2017

Why does this code to initialize a string to a single character call the initializer_list constructor?

I was recently working on a C++ project and came across an edge case with the string constructors that I can't fully understand. The relevant code (which you can run here) is as follows:

#include <iostream>
#include <string>
using namespace std;

int main() {
    string directParens(1, '*');
    string directBraces{1, '*'};
    string indirectBraces = {1, '*'};

    cout << directParens.size() << endl;   // 1
    cout << directBraces.size() << endl;   // 2
    cout << indirectBraces.size() << endl; // 2
    return 0;
}

The brace-initialized versions of the strings end up having two characters in them, namely, a char with numeric value 1 followed by a star.

I don't understand why the brace-initialized versions of the string invoke the initializer_list constructor rather than the constructor taking in a size and a character. The initializer_list constructor has this signature:

basic_string(std::initializer_list<CharT> init, 
             const Allocator& alloc = Allocator());

Given that string is an alias for basic_string char, the specific signature would be

string(std::initializer_list<char> init, 
       const Allocator& alloc = Allocator());

How is the initializer {1, '*'}, which contains elements both of type int and of type char, matching this constructor? I was under the impression that all literals in an std::initializer_list must have the same type - is that incorrect?

Aucun commentaire:

Enregistrer un commentaire