Почему преобразование std :: initializer_list не является предпочтительным?

Рассмотрим этот фрагмент:

#include <iostream>
#include <vector>

void f(std::vector<int>){std::cout << __PRETTY_FUNCTION__ << '\n';}
void f(int x){std::cout << __PRETTY_FUNCTION__ << '\n';}

int main() 
{
    f({42});
}

Live on Coliru

Если вы запустите его, вы увидите, что предпочтительна перегрузка f(int), хотя std::vector имеет конструктор std::initializer_list (см. # 8).

Вопрос: Почему преобразование {42} в int предпочтительнее (вместо преобразования в std::vector, поскольку {42} является std::initializer_list)?

Ответы

Ответ 1

При разрешении перегрузки, когда рассматривается неявная последовательность преобразования в инициализации списка,

(акцент мой)

В противном случае, если тип параметра не является классом, а в списке инициализаций имеется один элемент, неявная последовательность преобразования - это та, которая требуется для преобразования элемента в тип параметра

Для f({42}); , для f(int) неявная последовательность преобразования является той, которая преобразует элемент (т.е. 42) в int, что является точным совпадением; для f(std::vector<int>) требуется пользовательское преобразование (преобразование std::initializer_list<int> в std::vector<int>), тогда это хуже.

PS: если бит-инициализатор содержит более одного элемента, такого как {42, 42}, будет выбран f(std::vector<int>).