user49535
user49535

Reputation: 15

Why is call of overloaded 'function(std::string)' is ambiguous?

The code is as below. Since the number of parameters is different, the call should not be ambiguous. One of the constructors accepts a string and other string plus integer. Why do I get the error?

#include <iostream>
#include <string>

using namespace std;

class AmbiguosCheck {

public:
AmbiguosCheck(string checkId = string(""),
int length = 0) :
checkId_(checkId),
length_(length){}

AmbiguosCheck(string xmlstring)
{
fromStringForInternalTransfer(xmlstring);
}

string checkId_;
int length_;

string toStringForInternalTransfer(){
return checkId_ + "|" + to_string(length_);
}

void fromStringForInternalTransfer(string xmlstring)
{
checkId_ = xmlstring; //Using simple assigment for sample code. Need to split, convert and assign the values.
length_ = 20;
}
};

int main()
{
AmbiguosCheck bd((string)"Check ID|20.000");
}

Compilation error:

In function 'int main()':  
35:44: error: call of overloaded 'AmbiguosCheck(std::string)' is ambiguous  
35:44: note: candidates are:  
14:5: note: AmbiguosCheck::AmbiguosCheck(std::string)  
9:5: note: AmbiguosCheck::AmbiguosCheck(std::string, int)  
6:7: note: AmbiguosCheck::AmbiguosCheck(const AmbiguosCheck&)  
6:7: note: AmbiguosCheck::AmbiguosCheck(AmbiguosCheck&&)  

And why are there 2 more candidates for ambiguity?

Upvotes: 0

Views: 1254

Answers (2)

Fire Lancer
Fire Lancer

Reputation: 30145

AmbiguosCheck(string checkId = string(""), int length = 0) AmbiguosCheck(string xmlstring)

So if you have AmbiguosCheck(myString) which is it to call?

AmbiguosCheck(myString, 0); // first constructor, because length = 0 default
AmbiguosCheck(myString); // second single argument constructor

Does having the second constructor actually makes sense? If length = 0 is a proper default, just keep that one.

Otherwise maybe get rid of the default values, and have a default constructor.

AmbiguosCheck() { ... }
AmbiguosCheck(string xmlstring) { ... }
AmbiguosCheck(string checkId, int length) { ... }

Which can all be called unambiguously.

AmbiguosCheck a; // default constructor ()
AmbiguosCheck b(myString); // string
AmbiguosCheck c(myString, n); // string, int

Upvotes: 1

lubgr
lubgr

Reputation: 38315

The first constructor specifies a default value for the second int argument. This can hence be left out, which then leaves you with two constructors that both can be invoked with one std::string argument. This is indeed ambiguous.

To fix this, you can remove the = 0 default parameter, by passing the integral second argument as a (non-defaulted) std::optional<int> (C++17 is required, then) or go with named static factory functions.

Upvotes: 1

Related Questions