转换到'常量Y`不适用的r &&`上铛(Conversion to `con

2019-09-23 16:36发布

下面的代码编译细跟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;
}

改变转换操作者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) {}
       ^

编辑:不幸的是即使添加了过载

void f(const Y&) {}

还是让铛选择右值引用过载,因此这打破现有的代码,用来编译精细,例如用标准集装箱。

Answer 1:

我相信铛是有权拒收此。 传递的参数f(Y&&)需要两个转换步骤,第一个是你的operator const Y()第二个是Y的拷贝构造函数。 既算作用户定义的转换,我想,又都是隐式的,这违反了一个隐式转换序列仅包括一个用户定义的转换的原理。

这通过常量的值返回的目的是什么? 包含了一些有趣的见解返回的语义const T

嗯,如果我尝试添加过载void f(const Y&y)作为编辑的问题,现在呢,铛表现相当strangly。 它仍然抱怨自己无法转换XY ,甚至不列出过载f(const Y& y)在其诊断。 但是,一旦我改变过载采取Y由值,即写void f(const Y y)它抱怨调用f是暧昧。

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



Answer 2:

是形成不良的的例子。

有些N3242报价。

8.5.3第4段:

给定类型的“CV1 T1 ”和“CV2 T2 ”,“CV1 T1 ”是参考有关“CV2 T2 ”如果T1是相同的类型T2 ,或T1是一个基类的T2“CV1 T1 ”是参考兼容“CV2 T2 ”如果T1是参考相关于T2CV1是相同的CV-资格,或更大的CV-资格比,CV2。

第5款(子弹标签是我的):

键入“CV1参考T1 ”是通过类型“CV2的表达式初始化T2 ”,如下所示:

  1. 如果参考是一个左值引用和...
  2. 否则,应参考是一个左值参照非易失性const型(即CV1const ),或参考应一个rvalue参考。

    一种。 如果初始化表达式

    • 一世。 是一个x值,类prvalue,阵列prvalue或功能左值和“CV1 T1 ”被参考兼容“CV2 T2 ”,或
    • II。 有一个类类型(即T2是一个类型),其中, T1是不能引用相关于T2 ,并且可以被隐式转换为x值,类prvalue,或类型“CV3的功能左值T3 ”,其中“CV1 T1 ”是参考兼容“CV3 T3 ”,
    • 那么引用绑定到....

    湾 否则,一个临时的型“CV1T1被创建”,并从使用用于非参考副本初始化(8.5)的规则初始化表达式初始化。 然后,将参考结合于暂时的。 如果T1被参考相关到T2 ,CV1应是相同的CV-资格,或更大的CV-资格比,CV2。 ...

对于函数参数初始化, T1YT2X ,和CV1CV2都为空。 图1是出:所述参考是一个rvalue参考,而不是左值参考。 2.ai是出: X是不是参考兼容与Y 。 2.B. 是,因为复制初始化Y从类型的prvalue X包括两个用户定义的转换:转换函数,然后的拷贝构造Y 。 (确切的禁止是13.3.3.1p4。)

对于情况2.a.ii.,对于“CV3显而易见的选择T3 ”是const Y ,但是这是没有好,因为Y没有参考兼容与const Y 。 你可能会认为对于试图T3YCV3是空的,但你又回到了需要的拷贝构造函数Y作为第二隐含的用户定义的转换。



文章来源: Conversion to `const Y` not applicable for `R&&` on clang