调用重载的“<brace-enclosed initializer list>”与足够的对是不明确的

Gyu*_*hoi 5 c++ overloading c++11 c++17

我无法编译以下代码。

void print_number(long n) {
   std::cout << n << std::endl;
}

void print_number(float n) {
   std::cout << n << std::endl;
}

void print_pair(std::pair<std::string, long> p) {
   std::cout << std::get<1>(p) << std::endl;
}

void print_pair(std::pair<std::string, float> p) {
   std::cout << std::get<1>(p) << std::endl;
}

int main() {
   print_number(12l);
   print_number(3.4f);

   print_pair({"long", 12l});
   print_pair({"float", 3.4f});

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

print_number功能运行良好。然而,编译器抱怨重载的print_pair函数: error: call of overloaded ‘print_pair(<brace-enclosed initializer list>)’ is ambiguous.

够用<brace-enclosed initializer list>还是std::pair不工作?如何重载接收std::pair参数的函数?

Bia*_*sta 3

太;博士

为了解决歧义,您可以向编译器提供正确的类型:

print_pair(std::make_pair<std::string, long>("long", 12l));
print_pair(std::make_pair<std::string, float>("float", 3.4f));
Run Code Online (Sandbox Code Playgroud)

或者

print_pair(std::make_pair(std::string("long"), 12l));
print_pair(std::make_pair(std::string("float"), 3.4f));
Run Code Online (Sandbox Code Playgroud)

歧义问题并非源于事实"long",而是源于"float"事实。std::stringconst char[]

std::pair因此,当您尝试使用以下表达式构造 a 时std::pair{"long", 12l},您获得的是 a 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>
Run Code Online (Sandbox Code Playgroud)

为了“证明”问题是std::string(不是long或),您还可以通过构造一个正确的(而不是 的数组)float来解决歧义:std::stringchar

print_pair(std::make_pair(std::string("long"), 12l));
print_pair(std::make_pair(std::string("float"), 3.4f));
Run Code Online (Sandbox Code Playgroud)

从C++17开始,这个样板可以简化为:

using namespace std::string_literals;

print_pair(std::pair{"long"s, 12l});
print_pair(std::pair{"float"s, 3.4f});
Run Code Online (Sandbox Code Playgroud)