我目前正在一个小项目中,我在其中操作枚举:
enum ThreeVal_t {T='T',F='F',U='U'};
我想创建Atom
。
定义如下:
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();
};
运算符的定义如下
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++;
}
我的问题是,当我调用Atom a(U)
时,我从clang编译器收到以下错误消息:
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);
但是我认为由于声明和定义不同,因此可以正常工作。 你知道为什么会模棱两可吗?
答案 0 :(得分:1)
问题在于表达式中:
Atom A(U)
U
同样可以正确地解释为对U
或U
副本的引用。因此,它绑定到两个构造函数签名。这就是模棱两可的根源。
通常,您需要选择一种签名。如果要复制(或将临时对象移入对象),则按值传递。如果要使用对现有对象的不可变引用,该引用将在调用构造函数后继续存在,请通过const reference传递。
class Atom
{
// ...
public:
// pass by value
Atom(ThreeVal_t at);
// ...
};
class Atom
{
// ...
public:
// pass by const reference
Atom(ThreeVal_t const & at);
// ...
};