Reputation: 3
I am currently working on a small project, where I manipulate an enumeration :
enum ThreeVal_t {T='T',F='F',U='U'};
And I want to create Atom
.
Defined as follows :
class Atom :
{
private:
std :: string name;
ThreeVal_t val;
static int id;
public:
//constructors
Atom();
Atom(const Atom &at);
Atom(const ThreeVal_t at);
Atom(const ThreeVal_t &at);
//Destructor
~Atom();
};
Operators are defined as follows
Atom::Atom() : name("a_" + std::to_string(id)), val(U)
{
id++;
}
Atom::Atom(const Atom &at) : name("a_" + std::to_string(id)), val(at.val)
{
id++;
}
Atom::Atom(const ThreeVal_t at) : name("a_" + std::to_string(id)), val(at)
{
id++;
}
Atom::Atom(const ThreeVal_t &at) : name("a_" + std::to_string(id)), val(at)
{
id++;
}
My problem is that when I call Atom a(U)
i get the following error from my clang compiler :
error: call to constructor of 'Atom' is ambiguous
Atom a(U);
^ ~
note: candidate constructor
Atom(const ThreeVal_t at);
^
note: candidate constructor
Atom(const ThreeVal_t &at);
^
note: candidate constructor
Atom(const Atom &at);
But I thought that since the declaration and definition were different, it would work. Do you know why it's ambiguous?
Upvotes: 0
Views: 39
Reputation: 69854
The problem is that in the expression:
Atom A(U)
U
can equally correctly be interpreted as a reference to U
or a copy of U
. It therefore binds to both constructor signatures. This is the source of the ambiguity.
In general you'll want to choose one of the signatures. If the intent is to take a copy (or move a temporary into the object) then pass by value. If the intent is to work with an immutable reference to an existing object that will persist after the call to the constructor, pass by const reference.
class Atom
{
// ...
public:
// pass by value
Atom(ThreeVal_t at);
// ...
};
class Atom
{
// ...
public:
// pass by const reference
Atom(ThreeVal_t const & at);
// ...
};
Upvotes: 1