9

これは、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 ++は正しいですか?

: これは、の修飾子が意味を成すかどうかの問題ではありません。これは、どのコンパイラが標準に準拠して動作するかについてであり、それについてのみですconstcast_type

¹ 2014 年はここで違いを生むべきではありません。

編集:

これを汎用の c++ タグで再度タグ付けすることはお控えください。私はまず、どの動作が 2011 規格に準拠しているかを知りたいと思います。そして、委員会の献身not to break existing (< 2011) codeを今のところ ansatz から遠ざけておきます。

4

1 に答える 1