2011-12-30 21 views
5

暗黙的に変換オブジェクトを移動オーバーロードされた関数を呼び出すときにこのプログラムはclang++ test.cpp -std=c++0xを使用してコンパイルされません。コンパイルエラー

class A 
{ 
public: 
    A() {} 
    A(const A&) {} 
    A(A&&) {} 
    A& operator = (const A&) { return *this; } 
    A& operator = (A&&) { return *this; } 
}; 

class B 
{ 
    A m_a; 
public: 
    operator const A &() const 
    { 
     return m_a; 
    } 
}; 

int main(int, char**) 
{ 
    A a; 
    B b; 
    a = b; // compile error 
} 

はエラーをコンパイルします。

Apple clang version 3.0 (tags/Apple/clang-211.10.1) (based on LLVM 3.0svn) 

test.cpp:25:9: error: no viable conversion from 'B' to 'A' 
    a = b; 
     ^
test.cpp:5:5: note: candidate constructor not viable: no known conversion from 'B' to 
     'const A &' for 1st argument 
    A(const A&) {} 
    ^
test.cpp:6:5: note: candidate constructor not viable: no known conversion from 'B' to 'A &&' 
     for 1st argument 
    A(A&&) {} 
    ^
test.cpp:15:5: note: candidate function 
    operator const A &() const 
    ^
test.cpp:8:23: note: passing argument to parameter here 
    A& operator = (A&&) { return *this; } 
        ^

なぜそれがコンパイルされませんか?なぜコンパイラはA::operator = (const A&)よりもA::operator = (A&&)を好むのですか?

さらに、A a; a = b;(上記のプログラム)とA a(b);の両方がコンパイルされているのに、なぜA a = b;がコンパイルされるのですか?

+0

どのようなバージョンのClangですか? – ildjarn

+3

FWIW、あなたのコードは 'clang version 3.0(tags/RELEASE_30/final)でそのままコンパイルします 対象:x86_64-pc-linux-gnu スレッドモデル:posix'とGCC 4.5.3または4.6.2それが正常かどうかは分かりません) – Mat

+0

クラングバグのようです。 –

答えて

4

これはどういうバグなのかよく分かりませんが、テストしているClangのバージョンは、特にC++ 11の機能に関してかなり古いものです。少なくともこのAFAIKを正しく受け入れる3.0 release of Clangを使用することをお勧めします。私はClang SVNトランクの最近の改訂版でそれをテストし、うまくいきました。

ClangのC++ 11のサポートはまだまだ非常に積極的に行われているため、3.0リリースにもバグがある場合は驚かないでください。あなたは、SVNトランクから直接ビルドすることで、より多くの成功を収めることができます。 Subversionからコードをチェックアウトし、Clangバイナリの新しいセットを構築するための命令hereがあります。