三元运算符适用于转换操作员的类,并删除构造函数会导致歧义

发布于 2025-01-29 01:33:49 字数 615 浏览 2 评论 0 原文

struct A {
  A();
  A(int) = delete;
  operator int(); 
};

int main() {
  true ? A{} : 0;
}

使用C ++ 20编译,Clang接受它,但是GCC和MSVC使用类似的错误消息

<source>(8): error C2445: result type of conditional expression is ambiguous: types 'A' and 'int' can be converted to multiple common types
<source>(8): note: could be 'A'
<source>(8): note: or       'int'

INT 拒绝它,因为构造函数是 a ,因为构造函数是代码>删除,但我不确定为什么GCC/MSVC仍然认为可以。哪个编译器是对的?

demo

struct A {
  A();
  A(int) = delete;
  operator int(); 
};

int main() {
  true ? A{} : 0;
}

Compile with C++20, Clang accepts it, but GCC and MSVC reject it with similar error messages

<source>(8): error C2445: result type of conditional expression is ambiguous: types 'A' and 'int' can be converted to multiple common types
<source>(8): note: could be 'A'
<source>(8): note: or       'int'

int doesn't seem to be convertible to A since the constructor is delete, but I'm not sure why GCC/MSVC still thinks it can. Which compiler is right?

(Demo)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

想念有你 2025-02-05 01:33:50

我认为GCC和MSVC在拒绝代码方面是正确的,因为A 删除功能在超载分辨率期间仍将进行。这意味着有两种可能性。

首先是 a {} 可以通过转换函数转换为 int 。其次是,即使 0 无法转换为 a ,相应的转换构造函数 a :: A :: A(int)< /代码>仍将参与过载分辨率。因此,存在歧义(关于要转换的操作数),并且程序不应编译(如GCC和MSVC中)。

来自条件操作员的文档

[注2:诸如访问之类的属性,操作数是位景点还是 是否删除了转换功能
忽略
为此决定。 - 终点注]


I think that gcc and msvc are correct in rejecting the code because a deleted function will still take part during overload resolution. This means that there are two possibilties.

First is that A{} can be converted to a int via the conversion function. Second is that even though 0 can't be converted to A , the corresponding converting constructor A::A(int) will still take part in overload resolution. Hence, there is ambiguity(about which operand to convert) and the program should not compile(as in GCC and MSVC).

From conditional operator's documentation:

[Note 2 : Properties such as access, whether an operand is a bit-field, or whether a conversion function is deleted are
ignored
for that determination. — end note]

孤独患者 2025-02-05 01:33:49

这似乎是

在其解决方案(2016年使用C ++ 17)之前,相关措辞询问是否可以将任何一个操作数转换为“转换为”,以从其他操作数类型形成的目标类型。

通过问题描述,似乎应该考虑使用此转换中使用的构造函数/转换操作员是否删除的原始措辞以及周围的措辞有些模棱两可,并且问题描述似乎表明一个严格的阅读导致令人惊讶的结果不一致。我不知道该问题中的解释将如何适用于您的案件,但是考虑到该问题的作者,我不会感到惊讶。

在任何情况下,问题的分辨率都将措辞更改为“ 是否可以形成隐式转换序列”,该序列与过载分辨率一致,并且绝对不考虑所选的隐式转换顺序是否会实际上导致了良好的转换,特别是是否可以访问/删除使用的功能。

还添加了@Anooprana在答案中引用的注释,以表明这一点。

使用新措辞,可以从 a {} int 0 a 的转换序列。因此,操作员是模棱两可的。 MSVC和GCC现在是正确的。

clang列出了当前时间的缺陷报告1895的实现状态为“未知”()仍然有一个匹配CWG问题描述在这里

This seems to be a variant of CWG issue 1895.

Before its resolution (in 2016 with C++17) the relevant wording asked whether either operand could be "converted" to the target type formed from the other operand's type.

Going by the issue description, it seems this original wording, as well as the wording around it, were somewhat ambiguous in whether or not deletedness of the used constructor/conversion operator in this conversion should be considered and the issue description seems to indicate that a strict reading lead to surprisingly inconsistent results. I don't know exactly how the interpretation in the issue would apply to your case, but I would not be surprised if it matches Clang's behavior, given the issue's author.

In any case, the resolution of the issue changed the wording to whether "an implicit conversion sequence can be formed", which is in line with overload resolution and definitively does not consider whether the chosen implicit conversion sequence will actually result in a conversion that is well-formed, in particular whether or not the used functions are accessible/deleted.

The note referenced in the answer by @AnoopRana was also added with that resolution to make this clear.

With the new wording, both the conversion sequences from A{} to int and 0 to A can be formed and hence the operator is ambiguous. MSVC and GCC are correct now.

Clang lists defect report 1895's implementation status as "unknown" at the current time (https://clang.llvm.org/cxx_dr_status.html) and still has an open bug matching the CWG issue description here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文