这是一个简短的示例,它使用柠檬为 clang 重现了这种“不可行的转换”,但对于 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;
}
住在 Godbolt's
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++ 正确接受它?
Nota bene:这不是关于那个const
限定词是否cast_type
有意义的问题。这是关于哪个编译器符合标准并且仅关于那个。
¹ 2014 在这里不应该有所作为。
编辑:
请不要使用通用 c++ 标记重新标记它。我首先想知道哪种行为符合 2011 年标准,并且暂时让委员会的奉献精神远离not to break existing (< 2011) code
ansatz。