2017-11-13 64 views
6

Ten program jest kompilowany przez brzękiem:dzyń: inicjowanie odwołanie blokady z mutex

#include <mutex> 

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

Inne główne kompilatory odrzucić go (Próbowałem gcc, msvc i ICC). To jest komunikat o błędzie z gcc:

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

Inne podają podobne błędy.

Czy klang jest dobry czy nie? Czy można to powtórzyć za pomocą prostszego przykładu nie obejmującego klas bibliotecznych? Próbowałem, ale bezskutecznie.

Edit to wydaje się być minimalna reprodukcji:

struct A {}; 

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

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

ciekawe, int zamiast A nie wywoła komunikat o błędzie w brzękiem (dlatego nie mogę odtworzyć ten początkowo).

Odpowiedz

2

Nie mam odpowiedniego rozdziału i wersetu standardu C++; Mogę odnosić się tylko do CppReference on Converting Constructors teraz (Kopalnia nacisk):

Konstruktor to nie zadeklarowany ze specyfikacją wyraźny i która może być wywołana z jednym parametrem (do C++ 11) nazywa się konwertujący konstruktor.

przeciwieństwie wyraźne konstruktorów, które prowadzone jedynie w bezpośrednim inicjalizacji (obejmujące wyraźne konwersji, takich jak static_cast), konwersję konstruktory są wzięte pod uwagę podczas inicjalizacji kopiowaniem, w ramach sekwencji konwersji zdefiniowany przez użytkownika.

Więc:

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

Tak ... to jest po prostu bug dzyń? Wygląda tak w moich oczach ... –

+0

@ n.m .: Nie mam kwalifikacji do * tego * konkretnego połączenia. Powyższe jest po prostu sposobem wyjaśnienia komunikatu o błędzie dla siebie; Zostawię wyrok wyższym władzom ... ;-) – DevSolar