使用隐式可转换对象调用移动重载函数时编译错误

时间:2011-12-30 18:23:05

标签: c++ c++11 overloading clang move-semantics

此程序无法使用clang++ test.cpp -std=c++0x编译:

class A
{
public:
    A() {}
    A(const A&) {}
    A(A&&) {}
    A& operator = (const A&) { return *this; }
    A& operator = (A&&) { return *this; }
};

class B
{
    A m_a;
public:
    operator const A &() const
    {
        return m_a;
    }
};

int main(int, char**)
{
    A a;
    B b;
    a = b; // compile error
}

编译错误:

Apple clang version 3.0 (tags/Apple/clang-211.10.1) (based on LLVM 3.0svn)

test.cpp:25:9: error: no viable conversion from 'B' to 'A'
    a = b;
        ^
test.cpp:5:5: note: candidate constructor not viable: no known conversion from 'B' to
      'const A &' for 1st argument
    A(const A&) {}
    ^
test.cpp:6:5: note: candidate constructor not viable: no known conversion from 'B' to 'A &&'
      for 1st argument
    A(A&&) {}
    ^
test.cpp:15:5: note: candidate function
    operator const A &() const
    ^
test.cpp:8:23: note: passing argument to parameter here
    A& operator = (A&&) { return *this; }
                      ^

为什么不编译?为什么编译器更喜欢A::operator = (A&&)而不是A::operator = (const A&)

此外,为什么A a = b;(上述程序)和A a; a = b;都不会编译A a(b);

1 个答案:

答案 0 :(得分:4)

我不确定这是什么bug,但是你测试的Clang版本相当陈旧,特别是在C ++ 11功能方面。你可能想要至少使用正确接受这个AFAIK的3.0 release of Clang。我用最近修订的Clang SVN主干进行了测试,结果很好。

鉴于Clang的C ++ 11支持仍处于非常活跃的开发阶段,如果3.0版本中也存在漏洞,请不要感到惊讶。您可以直接从SVN中继构建更多成功。有一些说明here用于检查subversion中的代码并构建一组新的Clang二进制文件。