转换为`const Y`不适用于clang上的`R &&`

pmr*_*pmr 5 c++ g++ clang move-semantics c++11

以下代码编译良好g++ (GCC) 4.7.1 20120721,但最近构建失败clang version 3.2 (trunk).

struct Y {};

struct X {
  operator const Y() const { return Y(); }
};

void f(Y&& y) {}

int main()
{
  f(X());
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

将转换运算符更改operator Y() const为足以使代码在两个编译器上进行编译.

在这种情况下,哪个编译器实际上符合标准?标准实际上对此有何看法?

请求的逐字错误:

bla.cpp:14:5: error: no viable conversion from 'X' to 'Y'
  f(X());
    ^~~
bla.cpp:1:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'X' to
      'const Y &' for 1st argument
struct Y {
       ^
bla.cpp:1:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'X' to
      'Y &&' for 1st argument
struct Y {
       ^
bla.cpp:6:3: note: candidate function
  operator const Y() const { return Y(); }
  ^
bla.cpp:10:12: note: passing argument to parameter 'y' here
void f(Y&& y) {}
       ^
Run Code Online (Sandbox Code Playgroud)

编辑:不幸的是甚至添加了过载

void f(const Y&) {}
Run Code Online (Sandbox Code Playgroud)

仍然让clang选择rvalue引用重载,这样就破坏了用于编译的现有代码,例如使用标准容器.

fgp*_*fgp 6

我相信铿锵是拒绝这一点的权利.传递参数f(Y&&)需要两个转换步骤,第一步是你的operator const Y(),第二步是Y复制构造函数.我认为两者都算作用户定义的转换,并且都是隐式的,这违反了隐式转换序列仅包含一个用户定义的转换的原则.

这个以const值返回的目的?包含一些关于返回a语义的有趣见解const T.

嗯,如果我尝试添加一个重载,void f(const Y&y)就像现在编辑的问题一样,clang表现得相当苛刻.它仍然抱怨自己无法转换XY,甚至不列出超负荷f(const Y& y)其诊断.但是一旦我Y通过值改变了重载,即写入void f(const Y y),它就会抱怨f模糊不清.

这是与XCode 4.5的clang报道的Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn).如果你能重现此与香草铛,你应该铛邮件列表上报告这个-当然似乎有潜伏有一个错误的地方 ...