条件运算符“?:”的编译器错误与类型转换运算符一起使用时
以下代码采用最简单的形式:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这似乎是一个编译器错误。我在规范中检查了它,标准明确指出(§5.16/3 - C++03),
本节的其余部分解释了如何完成转换。没有什么可以阻止
*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),
and the rest of the section explains how the conversion is done. There is nothing that stops
*p
from implicitly converting intochar
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.
在某些版本的 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 页面上的链接时,结构定义有所不同,并且 是你错误的根源。
然后如上所述,结构不同,我确实收到了您看到的错误。 这是一个正确的错误,因为“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.
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.
错误是正确的。
?:
的操作数有不同的类型:第一个是“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.