在这种情况下,多个条件运算符是个好主意吗?

我刚看到关于条件运算符的维基百科文章中的这段代码:

Vehicle new_vehicle = arg == 'B' ? bus : arg == 'A' ? airplane : arg == 'T' ? train : arg == 'C' ? car : arg == 'H' ? horse : feet; 

我已经改变了一些代码,但想法是一样的。 您会发现条件运算符的这种使用是否可以接受? 它比ifelse结构更简洁,并且使用开关肯定会为bug提供一整套新的机会(任何人都可以使用?)。 此外, ifelseswitch不能用作R值,那么您必须先创建变量,初始化它然后根据需要进行分配。

我真的很喜欢这个,但我想知道其他人的想法。

但格式化至关重要。

编辑:我仍然喜欢这个。 但我理解那些说“ switch声明是为此做出的”。 好吧,也许是这样。 但是如果条件是返回bool函数调用呢? 或者其他一百万件你无法打开的东西。

你切换爱好者真的试图说服一个巨大的ifelse链更好吗? 是的,不知道如何使用条件运算符的程序员将无法理解这一点。 他们应该学习如何使用它。 这不是奥术。

我多次使用过这种结构。 只要它的格式很好(即不是所有在一行上,使其不可读),我没有看到它的问题。

我会使用一个开关,因为这是它的设计目的。 是的,存在掉线错误的风险,但这种嵌套条件块有被其他程序员误解的风险要高得多。

这是条件运算符使用的一个很好的例子。 我一直在C ++,Java和Perl中以这种方式使用它。

它不仅没有任何问题,它以最简洁明了的方式传达操作的意图。

用if else替换或切换构造需要代码片段

 "new_vehicle = " 

在每个实例中重复,这要求读者阅读它的每个重复实例,以确保它在每个实例中实际上是相同的。

我喜欢。 它类似于if-else-if阶梯,只是更简洁。

字符常量周围有很多空格,这使得它有点难以阅读。 我将比较括起来:(并且可能将最后一个值移动到行中。)

 Vehicle new_vehicle = (arg == 'B') ? bus : (arg == 'A') ? airplane : (arg == 'T') ? train : (arg == 'C') ? car : (arg == 'H') ? horse : feet; 

现在它看起来很棒。

条件运算符版本干净,简单,对任何知道C或C ++发生的事情的人来说都很明显。 它的另一个优点是它立即返回一个值,这意味着它可以放在初始化中(如本例所示)。

切换声明会更加笨拙。 它需要声明变量然后进行初始化,如果可以避免则通常是一个坏主意。 这需要更多的打字,并且会有更多的地方让虫子进入。它不会那么清楚,因为有必要查看每个案例,看它说像new_vehicle = foo; break; new_vehicle = foo; break;

如果你打算只在这里查看,那么条件版本就是好的,因为它会立即显示正在发生的事情。 如果它不止一次出现,可以考虑将它放在一个函数中,这样如果有任何变化,只有一个地方可以更新(例如,’R’表示运输或’L’表示直升机)。

纯粹是一种风格选择。 对于像你这样的小型数据集,只要你的编程团队没有被这样的东西抛出,那么我的书就好了。

开关更清晰,效率更高。 如果我在代码审查中看到这样的代码,我会担心的。 此外,这是“条件运算符” – 它是三元运算符的实例(尽管目前是C和C ++中唯一的实例)。

 Vehicle new_vehicle = getVehicleByType(arg); Vehicle getVehicleByType(char arg){ if (arg == 'B') return bus; if (arg == 'A') return airplane; if (arg == 'C') return car; if (arg == 'T') return train; if (arg == 'H') return horse; return feet; } 

我更喜欢这个。 嵌套条件是聪明的,但我认为这几乎是简洁的,不太可能混淆未来的读者。 对不起,如果语法关闭,我现在做的不多。

编辑:修复注释中注明的返回类型遗漏。 谢谢!

编辑:顺便说一下,我对你的版本并不感到恐惧。 当我看到它时,我没有惊叹WTF或OMG。 我只是更喜欢我的:)

我并不特别在意它。

它并没有真正购买任何东西,或者做得更清楚,而且这是一个非常非标准的运营商用途。

看来它的主要优点是它有点聪明。 我避免聪明,除非有一个很好的(外部)理由聪明。

我倾向于使用switch语句,因为编译器会捕获重复的情况。 可以说,这不是这个例子中的问题,但是如果列表变得非常长并且由几个不同的人处理,则很容易添加副本而不能实现它。

更仔细地阅读维基百科文章的C ++部分 。 它明确列出了一些使用?:运算符是唯一选项的情况,并且不能用if/elseswitch替换。

另一方面,我不会使用它只是因为它看起来更漂亮。

我以前从未见过这样的东西。 虽然它很聪明且格式良好,但这似乎是使用字典/散列表的绝佳机会(假设Vehicle是枚举,目前还不清楚)。

一些人已经提到过使用std::map或其他关联数组类型来完成这项工作的可能性。 只要您只是这样做是一个地方(或几个地方),您可能会考虑使用普通数组或向量:

 Vehicle vehicles[CHAR_MAX]; // Initialization std::fill_n(vehicles, CHAR_MAX, feet); vehicles['A'] = airplane; vehicles['B'] = bus; vehicles['C'] = car; vehicles['H'] = horse; vehicles['T'] = train; // Use Vehicle new_vehicle = vehicles[arg]; 

根据您需要/使用的表(存储相同类型的对象)的方式以及所包含对象的大小(在本例中为Vehicle),这可以是std::map的完全合理的替代方法。 如果你创建了很多表,或者每个对象都很大,那么std::map就变成了一个更合理的选择。

当您使用std::map (或unordered_map等)时,您将使用更多代码来节省数据存储空间。 这反过来 – 但只要Vehicle很小(例如,4个字节),像上面这样的一个表通常会占用半个千字节。 很难准确猜出std::map的代码对于特定的编译器来说有多大,但它似乎通常大于半千字节,所以如果你只创建一个像这样的表, std::map可能是净损失。

当然,如果你知道你只是处理字母作为输入,你可以减少表格大小:

 template  class letter_table { static const int range = 'Z' - 'A'; T table[range]; public: // ... T operator[](int index) { index -= 'A'; assert(index 

在示例中,这将给出一个大约100个字节的表 - 您可以在std::map通常占用的空间中创建相当数量的100字节表。

纯粹实用:

另外:三元序列更灵活,可用于避免switch的限制,您可以使用其他运算符(例如<=,> =)或任何其他测试,包括例如字符串比较。

 x = IsEven(arg) ? 0 : (arg < 0) ? -1 : 1; // or whatever 

此外,如果开关是性能瓶颈并且您的概率不均匀,则可以强制首先完成最可能的测试(由于未选择的路径未经评估保证)。

所以 -不像switch语句,顺序很重要(除非你坚持== )。 这可能是一个优势,但是当维护者不熟悉这个概念或者匆忙时,它可能会误导开关。

许多开发人员可能会回避,因为他们不确定细节(哪些术语将被评估,运算符的优点是否正确?) - 但是,如果您的开发人员池不能掌握一个很好的示例,那么您可能会有禁止三元运营商无法解决的问题。

减号它不像switch那样常见,因此优化器可能不会对它进行相同处理。 已知优化器为交换机选择最适合的实现(表,二进制搜索,比较序列或其任何组合)。 优化器无法重新排列wevaluaiton顺序,并且不太可能在此处支持表查找。

需要良好的格式才能轻松识别(排列'?'和':') - 使用标签时会很糟糕。

美学

我喜欢它的精确性和简洁性,接近数学符号。 但是,这可能也会被用来对付它。 它可能是代码审查中的一个提升者,因为它不太常见且更脆弱。

仅用于比较,在C ++ 0x中,您可以使用表达式而不使用条件运算符或外部函数:

 Vehicle new_vehicle = [&]() -> Vehicle { if (arg == 'B') return bus; if (arg == 'A') return airplane; if (arg == 'T') return train; if (arg == 'C') return car; if (arg == 'H') return horse; return feet; }(); 

然而,并没有更好。

怎么样:

 enum Vehicle { bus = 'B', airplane = 'A', train, car = 'C', horse = 'H', feet = 'F' }; ... new_vehicle = arg; 

:-), 顺便说说。

我认为它对编码它的人很有用,但是对于复兴者来说很难理解,

“保持简单的兄弟”

在我看来,由于示例的简单性,您所做的事情是可以接受的。 如果你在每个案例中做更多的事情,这种类型的构造可能会迅速变得混乱。 出于这个原因,我更喜欢一个开关,甚至是嵌套的if if elses(如果没有太多的情况),格式如下:

  if (A) { //Do A stuff } else if (B) { //Do B stuff } else if (C) { //Do C stuff } else { //Do default stuff } 

它是关于代码的可读性,这有助于代码的可维护性。 我从来都不是条件运算符的狂热粉丝,因为我不喜欢在一行上看到多个表达式。 单步执行调试器中的代码时,很难遵循条件运算符。 代码越简单,就越容易专注于代码所做的事情。

我们中的许多人习惯于各种报告工具中的Iif函数或Excel中的If函数,我们基本上需要使用不太清晰的Iif(arg =“B”;“Bus”; Iif(arg =“A”;飞机; “脚”))。 我喜欢你的样本相比:)我个人会使用if-elses,但我不会对你的样本有任何问题。