调用重载的构造函数会产生歧义错误C ++

时间:2019-11-10 09:46:59

标签: c++

我目前正在一个小项目中,我在其中操作枚举:

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);


但是我认为由于声明和定义不同,因此可以正常工作。 你知道为什么会模棱两可吗?

1 个答案:

答案 0 :(得分:1)

问题在于表达式中:

Atom A(U)

U同样可以正确地解释为对UU副本的引用。因此,它绑定到两个构造函数签名。这就是模棱两可的根源。

通常,您需要选择一种签名。如果要复制(或将临时对象移入对象),则按值传递。如果要使用对现有对象的不可变引用,该引用将在调用构造函数后继续存在,请通过const reference传递。

class Atom
{
  // ...
public:
    // pass by value
    Atom(ThreeVal_t at);
  // ...
};

class Atom
{
  // ...
public:
    // pass by const reference
    Atom(ThreeVal_t const & at);
  // ...
};