Clang不能使用括号初始化来进行用户定义的转换 [英] Clang cannot use braced initialization for user-defined conversion

查看:39
本文介绍了Clang不能使用括号初始化来进行用户定义的转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码如下.

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?

推荐答案

由于 DR1467 (cfr. 22259 )

最新版本的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆