Почему существует разница между шаблоном и автоматическим выводом типа для краевого случая std::initializer_list?

По сути, в C++11 существует три типа вывода типов:

  • шаблоны
  • auto
  • decltype

В большинстве случаев вывод типа auto и шаблонов, по-видимому, действует одинаково. Но есть один случай - когда мы устанавливаем переменную auto в значение, созданное инициализатором {}, заключенным в фигурные скобки, мы получаем ошибку компиляции

no match for call to '(std::initializer_list<int>) (<brace-enclosed initializer list>)' foo({0, 1, 2, 3});

Вот ссылка на пример кода: http://ideone.com/ODBAZ5

//foo's type would be deduced as std::initializer_list<int>
auto foo = {0, 1, 2, 3}; 

template<typename T> 
void bar(T t){};

//compiles fine
bar( foo );

//next line gives compiler error
bar({0, 1, 2, 3});

decltype — это совсем другая история, и это не относится к этому вопросу, но auto и шаблоны должны делать одно и то же (по крайней мере, это кажется разумным) при выводе типа — но они, очевидно, нет, и это сбивает с толку, почему?


person mr.pd    schedule 10.04.2015    source источник
comment
Какую ошибку компилятора вы получаете?   -  person NathanOliver    schedule 10.04.2015
comment
@ 0x499602D2 Я думаю, что OP спрашивает, почему существует специальное правило для auto, но не для шаблонов. Почему бы bar() не вывести bar<initializer_list<int>>?   -  person Barry    schedule 10.04.2015
comment
@ Барри - Да, именно так.   -  person mr.pd    schedule 10.04.2015
comment
@NathanOliver — добавлена ​​ошибка компилятора и ссылка на пример кода.   -  person mr.pd    schedule 10.04.2015