【问题标题】:What else does the condition operator in C++ do for me?C++ 中的条件运算符还能为我做什么?
【发布时间】:2011-09-30 06:33:22
【问题描述】:

我在使用条件运算符时遇到了一个奇怪的编译错误。

a,bint 的值,下面的表达式会出现编译错误。

(a>b)?( std::cout << a ) : ( b=MAX );
16 (b <unknown operator> 5)' 

(a>b)?( a=MAX ) : ( std::cout<<b );
16 (&std::cout)->std::basic_ostream<_CharT, _Traits>::operator<< [with _CharT = char, _Traits = std::char_traits<char>](b)' 

但是这个表达式效果很好,这很奇怪..

(a>b)?( std::cout << a ) : ( std::cout<<b );

我不知道是什么造成了这种差异,也不知道为什么编译错误代表什么。这是我的 gcc 信息:

Reading specs from ./../lib/gcc/mingw32/3.4.2/specs
Configured with: ../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as --host=
mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --enable
-languages=c,c++,f77,ada,objc,java --disable-win32-registry --disable-shared --e
nable-sjlj-exceptions --enable-libgcj --disable-java-awt --without-x --enable-ja
va-gc=boehm --disable-libgcj-debug --enable-interpreter --enable-hash-synchroniz
ation --enable-libstdcxx-debug
Thread model: win32
gcc version 3.4.2 (mingw-special)`

【问题讨论】:

  • 将带有副作用的语句放在条件表达式中看起来很丑。为什么不使用传统的 if 语句?
  • @Johannes:我已将您的评论标记为不具建设性。为什么不发表评论来解释为什么您如此不喜欢这个问题,而不是简单地粗鲁?
  • @Brennan 我认为提问者非常清楚这一点。我试图通过编辑它来修复它,但它是不可理解的。我从未见过像函数一样调用 16,也从未见过在 C++ 中使用 (这也不是 GCC 诊断)。如果你的问题格式不正确,在 SE 上呆了一年多,你至少需要以一种允许其他人格式化的格式来说明它。这就是为什么我-1'ed。我删除了我的其他评论,因为我发现它实际上没有帮助。

标签: c++ gcc conditional-operator


【解决方案1】:

条件运算符必须始终返回相同的类型。在您的第一个示例中,

(a > b) ? (std::cout << a) : (b = MAX);

第一个分支产生std::ostream 类型,第二个分支产生b 类型(考虑到它的上下文,它可能是一个整数)。你的第二个例子,

(a > b) ? (std::cout << a) : (std::cout << b);

没有这样的问题,因为两个分支都返回相同的类型,std::ostream。在任何一种情况下,使用简单的if-else 语句来处理这些情况可能会更干净。条件运算符往往会损害可读性,并且通常仅在有条件地分配给变量时有用:

int a = (a > b) ? a : b;
std::cout << a;

【讨论】:

  • 只是一点点(因为在全球范围内,您的答案比我的更好),但是a ? b : cbc 类型的规则有点复杂。基本上,编译器必须能够将其中一种类型转换为另一种类型。所以你可以有longint,或者Base*Derived*(但不是Derived1*Derived2*)。或者,其中一个表达式可以是 throw 表达式,在这种情况下,表达式的类型是另一种类型。
  • 事实上,例如,void *p = 0; (a &gt; b) ? (std::cout &lt;&lt; a) : (p = malloc(1)); 就可以了。
  • 解决此问题的另一种方法是使用逗号运算符:(a &gt; b) ? ((std::cout &lt;&lt; a), a) : (b = MAX); 这具有使代码更加晦涩的额外好处。 ;)
  • @James, Johannes:感谢您明确指出可以相互转换的类型也可以。我应该在我的回答中提到这一点。我也从未考虑在条件运算符中使用throw 表达式。就可读性而言,这是一个可怕的想法,但绝对是一个我没有考虑过的有趣的花絮。
  • @Michael 条件表达式中的throw 是否是一个可怕的想法取决于上下文。它在构造函数的初始化器中非常有用,例如(不能使用if)。
【解决方案2】:

?: 是表达式(或子表达式)中的运算符。表达式具有类型。 (a &gt; b) ? (std::cout &lt;&lt; a) : (b = MAX) 的类型应该是什么。 C++ 中的类型是静态评估的,编译器无法确定std::cout &lt;&lt; a(类型std::ostream&amp;)和b = MAX(类型int)的通用类型。

【讨论】:

  • 是的,这里的关键是“An expression has a type”部分
【解决方案3】:

C++ 中的条件运算符还能为我做什么?

嗯,它确实对第二个和第三个参数进行类型匹配,这对于从表达式中提取类型非常有用。有关如何使用条件运算符的该功能的令人兴奋的文章,请阅读here

【讨论】:

    猜你喜欢
    • 2011-07-09
    • 1970-01-01
    • 2014-09-16
    • 2019-04-01
    • 2013-02-25
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多