条件运算符“?:”的编译器错误与类型转换运算符一起使用时

发布于 2024-12-18 21:15:32 字数 562 浏览 3 评论 0原文

以下代码采用最简单的形式:

struct X {
  operator char () const { return 'a'; }
};

int main ()
{
  X obj, *p = &obj;
  char a = *p;  // ok
  char c = (true)? *p : 'z';
}

此代码给出编译器错误,如下所示:

错误:操作数?:具有不同类型“X”和“char”

class X< 中没有歧义时,为什么 *p 未解析为 char /code> 用于类型转换运算符 ? 这种虚假错误消息是正确的还是 g++ 错误?

[更新注意:有趣的是这种情况不会产生此类错误]

Following code is in simplest form:

struct X {
  operator char () const { return 'a'; }
};

int main ()
{
  X obj, *p = &obj;
  char a = *p;  // ok
  char c = (true)? *p : 'z';
}

This code gives compiler error as,

error: operands to ?: have different types ‘X’ and ‘char’

Why *p is not resolved to char when there is no ambiguity in class X for typecasting operator ?
Is such spurious error message correct or it's a g++ bug ?

[Update Note: Interestingly this scenario doesn't generate such error]

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

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

发布评论

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

评论(3

骄傲 2024-12-25 21:15:32

这似乎是一个编译器错误。我在规范中检查了它,标准明确指出(§5.16/3 - C++03),

否则,如果第二个和第三个操作数具有不同的类型,并且其中一个具有(可能是 cv 限定的)类类型,将尝试将其中每个操作数转换为另一个的类型 .

本节的其余部分解释了如何完成转换。没有什么可以阻止 *p 使用用户定义的转换运算符隐式转换为 char 类型。

另外,我用 (GCC) 4.5.0 编译了它。它没有给出任何错误,也带有 -pedantic 选项。尝试了-std=c++98-std=c++0x。仍然没有错误。

最肯定的是,这是一个编译器错误。

It seems to be a compiler-bug. I checked it out in the spec, the Standard clearly says (§5.16/3 - C++03),

Otherwise, if the second and third operand have different types, and either has (possibly cv-qualified) class type, an attempt is made to convert each of those operands to the type of the other.

and the rest of the section explains how the conversion is done. There is nothing that stops *p from implicitly converting into char type, using the user-defined conversion operator.

Also, I compiled it with (GCC) 4.5.0. It gives no error, with -pedantic option as well. Tried it -std=c++98 and -std=c++0x. Still no error.

Most definitely, it is a compiler-bug.

十二 2024-12-25 21:15:32

在某些版本的 G++ 中,条件运算符 ?: 的类之间的隐式转换存在问题。另外,根据版本的不同,您可能会看到错误,或者您可能/看不到/看到此类错误,但是您的所有三个示例都被 G++ 正确标记

这并不是对原始问题的答案,而是对原始发布者和其他人的重新认证,即 G++ 编译器可能存在虚假错误以及 ISOC++:2003 5.16 中指定的类类型转换行为的问题/3 [expr.cond]/3 (也由@Nawaz 在上面概述)

一个示例显示了原始海报示例的相反情况,其中可以发生两个方向的隐式转换但没有标记可以是参见此处

我在 G++ v3.4.6、v4.1.2、v4.2.1 和 v4.5.0(windows) 上编译了这个,没有发现任何问题,因为 @Nawaz 再次表示这是 ISOC++:2003 规范中的正确行为。

但是,当我点击您的 IDEONE 页面上的链接时,结构定义有所不同,并且 是你错误的根源。

struct X
{
  char ch;
  X(const char c) : ch(c) {}

  operator char () const { return ch; }
};

int main ()
{
  X obj('a'), *p = &obj;
  char a = *p; // ok
  char c = (true)? *p : 'b';
}

然后如上所述,结构不同,我确实收到了您看到的错误。 这是一个正确的错误,因为“z”可以转换为 X 或 char,并且由于构造函数“z”也可以转换为 X - X/“z”的双向性,因此编译器应该停止。 然而,只要稍加修改就可以通过,这与上面发布的 GNU G++ bug 完全相同。

如果将上面的示例转换为指针示例,它将失败。字符指针、int 指针或者其他什么。

虽然不相关,但我认为这可能是一个很好的观点,可以强调一些在 Windows/Linux 之间交叉移植时经常让我困惑的东西。如果 MSVC 认为转换是“安全的”,那么它通常会很高兴地通过此类转换,或者通常它可能会发出警告,表明转换正在进行时存在精度损失的风险 - 我不确定允许这样做的触发因素是什么。

There are issues with implicit conversion between classes for the conditional operator ?: in certain versions of G++. Also depending on the version you may either see an error, or you may /not/ see such an errors, however all three of your samples are correctly flagged by G++.

This is less of an answer to the original question but a re-certification of the original poster's, and others', qualm that there might be problems with spurious errors with G++ compiler and the conversion behavior for class types as specified in ISOC++:2003 5.16/3 [expr.cond]/3 (also outlined above by @Nawaz)

One example that shows the converse of the original poster's sample where implicit conversion in both directions can happen but isn't flagged can be seen here.

I compiled this on G++ v3.4.6, v4.1.2, v4.2.1 and v4.5.0(windows) and saw no problems because as again @Nawaz said this is the correct behavior within the ISOC++:2003 spec.

However, when I followed the link on your IDEONE page the structure definition was different and that is the root of your error.

struct X
{
  char ch;
  X(const char c) : ch(c) {}

  operator char () const { return ch; }
};

int main ()
{
  X obj('a'), *p = &obj;
  char a = *p; // ok
  char c = (true)? *p : 'b';
}

Then as above the struct is different and I do get the error your see. This is a correct error as 'z' can be converted into X or char, and because of the constructor 'z' can also be converted into X - bi-directionality of X/'z' so the compiler should stop. However with a little change it can be made to pass and that is exactly the same bug as the GNU G++ bug posted above.

If you convert your sample above to a pointer sample it will fail. Character pointer, int pointer or whatever.

Although unrelated I thought it might be a good point to highlight something that often caught me out whilst cross-porting between Windows/Linux. MSVC will happily pass such conversions often if it deems the conversion to be "safe", or often it may proffer a warning that conversion is being done at the risk of loss of precision - I am not sure what the trigger for allowing this is.

缱倦旧时光 2024-12-25 21:15:32

错误是正确的。 ?: 的操作数有不同的类型:第一个是“X”,第二个是“char”。编译器无法知道您希望表达式最终成为 char - 这会在整个表达式 (true) 求值之后发生? *p : 'z'; - 由于类型差异而无法首先进行评估。

The error is correct. operands to ?: have different types: ‘X’ the first, and ‘char’ the second. The compiler cannot know that you want the expression to be a char in the end - that will happen later, after the evaluation of the whole expression (true)? *p : 'z'; - an evaluation which cannot be done in the first place due to type discrepancies.

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