简体   繁体   中英

Overloaded function ambiguity

Firstly I should point out that this is my first stackoverflow question, so please bear with me.

I'm having some problems overloading a function in c++. I'm trying to create a function with the following prototypes:

void push_at_command(std::string, std::vector<std::string>, int);

void push_at_command(std::string, std::vector<std::string>, std::vector<std::string>, int);

void push_at_command(std::string, std::vector<std::string>, std::vector<std::string>, std::vector<std::string>, int);

void push_at_command(std::string, std::vector<std::string>, bool, int);

I originally wanted the last overload (the one with the boolean) to accept a boost::regex instead of a string vector;

void push_at_command(std::string, boost::regex, int);

but ran into ambiguity errors... so just to quickly get the code 'working' I thought I'd add a prototype to accept a flag, and use the first element in the vector to store a regex string, but I seem to be running into similar problems having the boolean.

This is how I'm trying to call these various overloads:

push_at_command(
    "AT?S", 
    boost::assign::list_of("(\\d{3}.\\d{3})"),
    true,
    0);
push_at_command(
    "AT?S", 
    boost::assign::list_of("L11")("L12"),
    0);
push_at_command(
    "AT?S", 
    boost::assign::list_of("L11"),
    boost::assign::list_of("L21")("L22"),
    0);

And this is the error I'm getting:

error: call of overloaded ‘push_at_command(const char [5], boost::assign_detail::generic_list<char [4]>, boost::assign_detail::generic_list<char [4]>, int)’ is ambiguous
note: candidates are:
note: void push_at_command(std::string, std::vector<std::basic_string<char> >, std::vector<std::basic_string<char> >, int)
note: void push_at_command(std::string, std::vector<std::basic_string<char> >, bool, int)

... which relates to the third function call.

Just to note, I had no problems before I added the overload with the bool (or changing the string vector to regex).

I am assuming the problem has something to do with me using boost::assign in the function call, and I realise that I don't need to, but I really need 'single line' function calls. ... Any advice welcome, as I am fairly new to C++.

Thanks

The problem is that as seen in the boost documentation, But what if we need to initialize a container? This is where list_of() comes into play. With list_of() we can create anonymous lists that automatically converts to any container: But what if we need to initialize a container? This is where list_of() comes into play. With list_of() we can create anonymous lists that automatically converts to any container:

In this case you don't want to be able to convert to any container, you want specifically s vector. Since you have this convertible type instead, it can't decide if it should convert to bool or vector, making the call ambiguous.

If you really want to continue with the overload set you've created (please take a step back and reconsider your approach using a flag) you'll need to specifically assign the list of into a vector (I'm assuming here that list_of provides a conversion operator to vector):

push_at_command(
    "AT?S", 
    boost::assign::list_of("L11"),
    std::vector<std::string>(boost::assign::list_of("L21")("L22")),
    0);

The error message tells you what the problem is. The call that's getting into trouble is the third one:

push_at_command(
    "AT?S", 
    boost::assign::list_of("L11"),
    boost::assign::list_of("L21")("L22"),
    0);

and the problem is that it can match both the third and fourth versions of push_at_command . They differ in the type of the third argument: one takes a vector and the other takes bool .

So the issue is that boost::assign::list_of("L21")("L22) can be converted to a vector and it can be converted to bool , and the rules do not prefer one of those conversions over the other. In a case like this, you have to help the compiler out, with a static_cast to the desired type. Or rethink the organization of these functions, and maybe re-order the arguments so that you don't get an ambiguity. (That's why, for example, std::string has a constructor that takes (int, char) and no constructor for a single char , which leads to ambiguities; it's an awkward interface, driven by too many overloads).

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