Clang不能使用括号初始化来进行用户定义的转换 [英] Clang cannot use braced initialization for user-defined conversion
问题描述
代码如下.
struct A {
A() {}
};
struct B {
B() {}
explicit operator A() { return A{}; }
};
struct C {
A a;
C(B b) : a{b} {}
};
我有一个 struct A
,它不能聚合构造(因为它定义了一个构造函数). struct B
也是如此.但是,它也具有用于 struct A
的明确的用户定义转换运算符.现在, struct C
的构造函数采用一个 struct B
,并使用它来构造 struct A
.与 cppreference 一样,转换操作员可以参与直接初始化,我相信这是 struct C
的成员初始化的情况.它通过了GCC 5.2(C ++ 11).但是,它在Clang 3.6上失败.我尝试使用C ++ 11,C ++ 14和C ++ 1z.
I have a struct A
which is not aggregate constructible (because it has a constructor defined). The same goes for struct B
. But it also has an explicit user-defined conversion operator to struct A
. Now struct C
's constructor takes a struct B
, and uses it to construct struct A
. As on cppreference, the conversion operator can participate in direct initialization, which I believe is the case for the member initialization of struct C
. It passes on GCC 5.2 (C++11). But however it fails on Clang 3.6. I tried with C++11, C++14, and C++1z.
如果我将 a {b}
更改为 a(b)
,它将同时传递Clang和GCC.
If I change a{b}
to a(b)
, it passes on both Clang and GCC.
我想知道这是Clang错误还是我误解了标准?
I wonder if it is a Clang bug or I misunderstood the standard?
推荐答案
最新版本的gcc和clang都做对了:编译代码没有错误.
Recent version of gcc and clang both do the right thing: compile your code without errors.
在成员初始值设定项列表的第一轮重载解析中,A的构造函数不是初始值设定项列表构造函数,因此将其丢弃.
In the first round of overload resolution for the member initializer list A's constructors are discarded since they're not initializer-list constructors.
随后 [over.match.list]/p1 接管
- 如果未找到可行的初始化器列表构造函数,则重载解析再次执行,候选功能全部是T类和参数列表的构造函数由初始化列表的元素.
这一次将A的构造函数考虑在内.A的copy和move构造函数具有足够的参数以匹配重载解析过程,并且自13.3.1.3甚至13.3.1.7起,它们都不会导致任何用户定义的转换抑制(仍在
and this time A's constructors are kept into account. A's copy and move constructors have enough arguments to match the overload resolution process and they don't cause any user-defined conversion suppression since 13.3.1.3 and even 13.3.1.7 (still in Clang's code) don't apply to these constructors.
因此,将它们输入到过载解决方案集中,并应用 [over.best.ics] .
Therefore they're entered in the overload resolution set and [over.best.ics] applies.
这篇关于Clang不能使用括号初始化来进行用户定义的转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!