clang:从互斥锁初始化锁定引用

n. *_* m. 6 c++ g++ clang

该程序由clang编译:

#include <mutex>

int main() {
    std::mutex mtx;
    const std::lock_guard<std::mutex>& lock(mtx);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

其他主要编译器拒绝它(我尝试过gcc,msvc和icc).这是来自gcc的错误消息:

error: invalid initialization of reference of type ‘const 
       std::lock_guard<std::mutex>&’ from expression of type ‘std::mutex’
Run Code Online (Sandbox Code Playgroud)

其他人给出了类似的错

是对还是错?这可以用一个不涉及库类的简单例子来复制吗?我试过但无济于事.

编辑这似乎是最小的再现:

struct A {};

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

int main()
{
    A a;
    const X& x(a);
}
Run Code Online (Sandbox Code Playgroud)

有趣的是int,替换A确实触发了clang中的错误消息(这就是我最初无法重现的原因).

Dev*_*lar 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
}
Run Code Online (Sandbox Code Playgroud)