【问题标题】:C++ operator order evaluationC++ 运算符顺序评估
【发布时间】:2019-12-04 10:08:40
【问题描述】:

我有代码,但它给了我一个编译错误。 我期望左右运算符顺序评估。 'name += ":"' 的结果是字符串,但看起来它首先评估了 ":" + "O"。我没有找到任何明确的解释。

#include <string>

int main()
{
  std::string name("HELL");
  name += ":" + "O";
  std::cout << "Hello, " << name << "!\n";
}

【问题讨论】:

标签: c++ operators evaluation


【解决方案1】:

表达式name += ":" + "O"分组name += (":" + "O")

但这将导致编译错误,因为":""0"const char[2] 类型,在该表达式中衰减为const char* 指针;和指针不能相加!

从 C++14 开始,您可以使用 user-defined-literal ""s+ 置于“字符串模式”:

name += ""s + ":" + "O"

分组规则被硬连线到语言语法中,尽管用operator precedence and associativity来思考很方便。

【讨论】:

  • 为什么不简单地name += ":"s + "O";?有什么区别吗?
  • @DanielsaysreinstateMonica:如果有的话,我会和我的编译器供应商进行严肃的交谈。但实际上你只需要使用":0";
  • 在 C++14 之前的版本中:name += std::string("") + ":" + "O" 也许?
  • @YSC,确实,虽然它没有那么可爱。 Java 人用 C++14 的方式来做。尽管这种语言比较可怕:不允许运算符重载,但随后以某种方式允许它用于java.lang.String
  • 或者你可以删除+:name += ":" "0";。预处理器连接相邻的字符串文字。这消除了临时的std::string 对象。
【解决方案2】:

根据operator precedenceoperator+的优先级高于operator+=,则name += ":" + "O";被解释为name += (":" + "O");,而":" + "O"无效,不能加两个指针(":""O" 会衰减为 const char* 类型的指针。

您可以添加() 来指定优先级,例如(name += ":") + "O";,它可以编译,但请注意 + "O" 部分在这里变得毫无意义。或者您可能希望 (name += ":") += "O";@Scheff 建议的那样,这取决于您的需求。

【讨论】:

  • 当你开始考虑用括号打破优先级时,也许,(name += ":") += "O";?
  • @Scheff 添加到答案中;它可能符合 OP 的意图,我不确定。 :)
  • @Scheff 哇,+= 的链接对我来说太难看了。我不太清楚为什么,因为我很乐意链接std::cout &lt;&lt; ... &lt;&lt; ...,但是用+= 这样做感觉不对。 :)
  • @Frodyne 因为()? operator+= 的关联性是从右到左的,没有() ":" += "O" 将首先被评估但它是无效的。
  • @Frodyne 多了几个参数后看起来真的很难看(越来越接近 Lisp 程序)。在这种情况下,最好改为重复 LHS。并不是说我认为它对编译器有影响,但它肯定对人的眼睛和情绪更好。
【解决方案3】:

这个带有复合赋值的表达式语句

name += ":" + "O";

其实等价于

name = name + ( ":" + "O" );

在这个子表达式中

( ":" + "O" )

字符串文字被转换为指向它们的第一个元素的指针。但是,二元运算符 + 没有为指针定义。所以编译器会报错。

您可以将原始语句拆分为两个语句,例如

name += ":";

name += "O";

在这种情况下,将使用为 std::basic_string 类定义的运算符 + 接受 const char * 类型的参数。

【讨论】:

  • (Nitpick: " 等同于 name = name + ..." - 需要注意的是表达式 name 只计算一次)。
  • @MaxLanghof 在这个问题的上下文中它完全不重要。
  • @VladfromMoscow:但是您提交了一个冗长的答案,所以我也认为您应该提及它。 (你注意到我在回答中完全避免了那罐蠕虫吗?!)
猜你喜欢
  • 2013-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-31
  • 1970-01-01
  • 2014-01-17
  • 2020-07-22
  • 1970-01-01
相关资源
最近更新 更多