При вызове v.emplace_back(a)
неявного преобразования не происходит. Если бы вы вызывали v.emplace_back<const std::uint16_t &>(a)
.
, то произошло бы неявное преобразование. Ключевое различие между push_back
и emplace_back
состоит в том, что последний является шаблоном, а первый - нет. Если вы не укажете аргумент шаблона для emplace_back
, компилятор выведет его из аргумента функции, что означает, что преобразование не потребуется в точке вызова. В пределах emplace_back
преобразование происходит в системном заголовке, который подавляет предупреждение.
Итак, в вашем примере
v.emplace_back(a);
выводится как
v.emplace_back<const std::uint32_t &>(a);
где ожидается, что аргумент функции будет std::uint32_t
. Идеальное совпадение, без необходимости преобразования за пределами системного заголовка. Если бы вы включили предупреждения в системных заголовках, вы могли бы получить кучу ложных предупреждений
Чтобы получить неявное преобразование в вашем коде, вам нужно заставить emplace_back
ожидать std::uint16_t
, что может быть выполнено через
v.emplace_back<const std::uint16_t &>(a);
Это неявно преобразует a
в std::uint16_t
перед вызовом emplace_back
, вызывая предупреждение компилятора так же, как push_back
.