これは、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;
}
ゴッドボルトに住む
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 から遠ざけておきます。