Tl; dr
Чтобы устранить неоднозначность, вы можете предоставить компилятору правильный тип:
print_pair(std::make_pair<std::string, long>("long", 12l));
print_pair(std::make_pair<std::string, float>("float", 3.4f));
или
print_pair(std::make_pair(std::string("long"), 12l));
print_pair(std::make_pair(std::string("float"), 3.4f));
Проблема неоднозначности возникает из-за того, что "long"
и "float"
не std::string
, а скорее const char[]
.
Так что, когда вы пытаетесь построить std::pair
, используя следующее выражение: std::pair{"long", 12l}
, то, что вы получите: std::pair<const char[5], long>
.
(То же самое для поплавка; т. е. std::pair<const char[5], float>
).
Ваша перегрузка print_pair
принимает std::pair<std::string, long>
или std::pair<std::string, float>
, Ни один из предыдущих типов не совпадает, поэтому компилятор должен выполнить преобразование. Из-за этого он не может автоматически определить, какое преобразование вы хотите выполнить. Оба действительны.
Например:
std::pair<const char[5], long>
|
----------------------------------------------------------------
v v
std::pair<std::string, long> std::pair<std::string, float>
Чтобы "доказать", что проблема заключается в std::string
(ни long
, ни float
), вы также можете устранить неоднозначность. построение правильного std::string
(вместо массива char
):
print_pair(std::make_pair(std::string("long"), 12l));
print_pair(std::make_pair(std::string("float"), 3.4f));
Начиная с C ++ 17 , этот шаблон может быть упрощен с помощью:
using namespace std::string_literals;
print_pair(std::pair{"long"s, 12l});
print_pair(std::pair{"float"s, 3.4f});