这是一个简短的示例,再现了“no viable conversion” with lemon for clang but valid for g++在编译器行为上的差异。
#include <iostream>
struct A {
int i;
};
#ifndef UNSCREW_CLANG
using cast_type = const A;
#else
using cast_type = A;
#endif
struct B {
operator cast_type () const {
return A{i};
}
int i;
};
int main () {
A a{0};
B b{1};
#ifndef CLANG_WORKAROUND
a = b;
#else
a = b.operator cast_type ();
#endif
std::cout << a.i << std::endl;
return EXIT_SUCCESS;
}
在bolt的上live
g++(4.9,5.2)会以静默方式进行编译;而clang++(3.5,3.7)编译它
如果
using cast_type = A;
或者
using cast_type = const A;
// [...]
a = b.operator cast_type ();
被使用,
,但默认值不是
using cast_type = const A;
// [...]
a = b;
在这种情况下,clang++(3.5)会怪
a = b
:testling.c++:25:9: error: no viable conversion from 'B' to 'A'
a = b;
^
testling.c++:3:8: note: candidate constructor (the implicit copy constructor)
not viable:
no known conversion from 'B' to 'const A &' for 1st argument
struct A {
^
testling.c++:3:8: note: candidate constructor (the implicit move constructor)
not viable:
no known conversion from 'B' to 'A &&' for 1st argument
struct A {
^
testling.c++:14:5: note: candidate function
operator cast_type () const {
^
testling.c++:3:8: note: passing argument to parameter here
struct A {
关于2011¹标准:clang++是否可以拒绝默认代码,或者g++是否可以接受默认代码?
注意::这是,而不是,是关于
const
上的cast_type
限定词是否有意义的问题。这是关于哪个编译器工作符合标准的,并且仅关于那个。¹2014年应该不会有所作为。
编辑:
请避免使用通用c++标记重新标记。
我首先想知道哪种行为符合2011年标准,并且暂时将委员会的奉献
not to break existing (< 2011) code
保留在ansatz之内。
最佳答案
因此,此clang错误报告rvalue overload hides the const lvalue one? 似乎涵盖了此示例,该示例具有以下示例:
struct A{};
struct B{operator const A()const;};
void f(A const&);
#ifdef ERR
void f(A&&);
#endif
int main(){
B a;
f(a);
}
失败,并显示与OP的代码相同的错误。理查德·史密斯(Richard Smith)最后说:
Update: we're correct to choose 'f(A&&)', but we're wrong to reject the initialization of the parameter. Further reduced:
struct A {}; struct B { operator const A(); } b; A &&a = b;
Here, [dcl.init.ref]p5 bullet 2 bullet 1 bullet 2 does not apply, because [over.match.ref]p1 finds no candidate conversion functions, because "A" is not reference-compatible with "const A". So we fall into [dcl.init.ref]p5 bullet 2 bullet 2, and copy-initialize a temporary of type A from 'b', and bind the reference to that. I'm not sure where in that process we go wrong.
但由于defect report 1604之后又返回了另一条评论:
DR1604 changed the rules so that
A &&a = b;
is now ill-formed. So we're now correct to reject the initialization. But this is still a terrible answer; I've prodded CWG again. We should probably discard f(A&&) during overload resolution.
因此,似乎clang在今天基于标准语言在技术上做对了,但是它可能会发生变化,因为至少从clang团队看来这是正确的结果。因此,大概这将导致缺陷报告,我们必须等到问题解决后才能得出最终结论。
更新
好像defect report 2077是基于此问题提交的。
关于c++11 - clang++失败,但g++成功在赋值中使用强制转换为const-unrelated-type运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33673158/