Подтвердить что ты не робот

Строка С++ - странное поведение при использовании конструктора списка инициализации

Я знаю, что я могу использовать массив символов, а также список инициализации, чтобы заполнить строку.

Похоже, что компилятор делает некоторую неявную рекламу от int до initializer_list или allocator. Но я не знаю, почему это не дает мне предупреждения и почему это делает его неявным.

Не могли бы вы объяснить мне, что происходит со строками s4 и s5?

http://ideone.com/5Agc2T

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

class A{
};

int main() {

    // string::string(charT const* s)
    string s1("12345");
    // 5 - because constructor takes into account null-terminated character
    cout << s1.size() << endl;      

    // string(std::initializer_list<charT> ilist)
    string s2({'1','2','3','4','5'});   
    // 5 - because string is built from the contents of the initializer list init.  
    cout << s2.size()<<endl;

    // string::string(charT const* s, size_type count)
    string s3("12345",3);
    // 3 -  Constructs the string with the first count characters of character string pointed to by s
    cout << s3.size() << endl;

    // basic_string( std::initializer_list<CharT> init,const Allocator& alloc = Allocator() ); - ?
    string s4({'1','2','3','4','5'},3);
    // 2 - why this compiles (with no warning) and what this result means?
    cout << s4.size() << endl;



    string s5({'1','2','3','4','5'},5);
    // 0 - why this compiles (with no warning) and what this result means?
    cout << s5.size() << endl;

    // basic_string( std::initializer_list<CharT> init,const Allocator& alloc = Allocator() );
    // doesn't compile, no known conversion for argument 2 from 'A' to 'const std::allocator<char>&'
    //string s6({'1','2','3','4','5'},A());
    //cout << s6.size() << endl;

    return 0;
}
4b9b3361

Ответ 1

string s6({'1','2','3','4','5'},3);
string s7({'1','2','3','4','5'},5);

Собственно, эти инициализации не просто вызывают конструктор std::initializer_list. Второй аргумент не может быть неявно преобразован в std::allocator, поэтому рассматриваются другие конструкторы. Вызываемый конструктор - тот, у кого есть эта подпись:

basic_string( const basic_string& other, 
              size_type pos, 
              size_type count = std::basic_string::npos,
              const Allocator& alloc = Allocator() );

Конструктор std::initializer_list используется для создания временного std::string из списка braced-init-list для передачи в качестве аргумента other указанного конструктора. Временное может связываться с этим, потому что оно ссылается на const. Таким образом, вторым аргументом является аргумент pos, который используется как отправная точка построения копии подстроки.

So s6 - это символы в интервале [3, 5) (т.е. "45"), а s7 - символы в интервале [5,5) (т.е. "").