2017-11-13 20 views
6

からロックの参照を初期化:打ち鳴らす:このプログラムは打ち鳴らすによってコンパイルされたミューテックス

#include <mutex> 

int main() { 
    std::mutex mtx; 
    const std::lock_guard<std::mutex>& lock(mtx); 
    return 0; 
} 

他の主要なコンパイラはそれを拒否(私はGCC、MSVC、およびICCを試してみました)。 gccからのエラーメッセージです:

error: invalid initialization of reference of type ‘const 
     std::lock_guard<std::mutex>&’ from expression of type ‘std::mutex’ 

他にも類例がありません。

clangは間違いなく正しいですか?これは、ライブラリクラスを含まないより単純な例で再現できますか?私は試したが役に立たなかった。

編集これは、最小限の再現のようだ:興味深いことに、Aの代わりにintは(私が最初にこれを再現することができなかった理由です)打ち鳴らすのエラーメッセージをトリガん

struct A {}; 

struct X 
{ 
    explicit X(A&) {}; 
}; 

int main() 
{ 
    A a; 
    const X& x(a); 
} 

答えて

2

私はC++標準の関連する章と節を持っていません。私は今CppReference on Converting Constructorsを参照することができます(強調鉱山):

ない明示的な指定子で宣言され、(C++ 11まで)と呼ばれる単一のパラメータで呼び出すことができますこれはコンストラクタ変換コンストラクタ

のみ(例えばstatic_castを明示的な変換を含む)直接初期化中に考慮ある明示的なコンストラクタとは異なり、変換コンストラクタは、ユーザ定義の変換シーケンスの一部として、コピーの初期化中に考慮されます。

ので:

struct A {}; 

struct X 
{ 
    explicit X(A const &) {}; 
}; 

int main() 
{ 
    A a; 
    const X& x1(A());     // OK, direct init (no A object after init) 
    const X& x3(a);     // NOK, copy init 
} 
+0

そう...これはちょうど打ち鳴らすのバグですか?それは私の目のように見える... –

+0

@ n.m .:私は*その*特定の呼び出しを行う資格はありません。上記は単なるエラーメッセージの説明です。私はその判断をより高い当局に委ねます... ;-) – DevSolar

関連する問題