简体   繁体   中英

Ambiguous call between `vector<long long>` and `vector<string>` with initializer_list input

Following code:

#include <iostream>
#include <vector>
#include <string>

void fun(const std::vector<long long> &x) {
  std::cout << "long long" << std::endl;
}

void fun(const std::vector<std::string> &s) {
  std::cout << "string" << std::endl;
}

int main() {
  fun({"a", "c"}); // ambiguous call.
}

can't compile due to ambiguous call. Why this happened? I didn't see any connection between const char * and long long .

I can write a new function to resolve ambiguity:

void fun(std::initializer_list<const char*> s)
{
    
}

But I still don't know what's happening.

std::vector<std::string> has a constructor that takes a std::initializer_list<std::string> as a parameter. This allows a std::vector<std::string> to be constructed from a std::initializer_list<std::string> .

However "a" and "b" are not std::string s, but string literals whose type is const char [n] (where n is a size of each literal string including the '\0' terminator); and when used in a std::initializer_list context they'll produce a std::initializer_list<const char *> .

Additionally C++ allows a maximum of one implicit conversion, but here two would be required: from std::initializer_list<const char *> to a std::initializer_list<std::string> (presuming that such an implicit conversion is even possible, it's not, so that's already a showstopper, but let's pretend there is one), and then from std::initializer_list<std::string> to a std::vector<std::string> , using a non- explicit constructor.

TLDR: the formal technical specification and rules for C++ run to more than thousand pages of text, and this is simply not allowed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM