{ 13, 42 }
- список инициализированных фигурных скобок.У него нет типа, это просто список, и это зависит от того, как он используется и как с ним обращаются.std::cbegin
определяется как
template< class C >
constexpr auto cbegin( const C& c ) -> decltype(std::begin(c));
, и поскольку список инициализированных фигурных скобок не имеет типа, вывод типа шаблона завершается ошибкой.В ранжированном цикле for мы используем другой список.Диапазон, основанный на цикле, расширяется до
{
init-statement
auto && __range = range_expression ;
auto __begin = begin_expr ;
auto __end = end_expr ;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
с auto && __range = range_expression ;
, становящимся auto && __range = { 13, 42 }
.Теперь auto
следует за вычетом типа шаблона, за исключением того, что, поскольку комитет решает, что auto
должен работать со списком инициализированных фигурных скобок , auto
выведет { 13, 42 }
в std::initiaizer_list<int>
, поскольку список содержит только int
с.
Если вы измените код на
copy_n(begin({ 13, 42 }), 2, ostream_iterator<int>(cout, " "));
, хотя std::begin
определен как cbegin
и принимает тип шаблона, <initializer_list>
вводит перегрузку , которая занимает std::initializer_list
и вместо этого вызывается.