表达式std::string {} = "..."的含义是什么?

16

在这段代码中:

#include <iostream>

int main(void)
{
    std::string {} = "hi";
    return 0;
}

这种声明在C++中是合法的。请参见Godbolt

  • 它是什么意思?
  • 它为什么是合法的?

补充信息,我测试了这个程序从c++11到c++20标志,因为从c++11开始可用扩展初始化器。


9
你创建了一个未命名的临时std::string,然后调用它的operator=(const char*)方法。 - UnholySheep
5
Godbolt可以带您进入CppInsights,如果您点击播放按钮,就会在右侧面板上获得“insight”视图,从而了解代码中发生的情况:https://cppinsights.io/s/194c6e89 - rturrado
Dupe1Dupe2Dupe3 - Jason
我很惊讶程序员投票重新开放了这个问题。 - Rohan Bari
显示剩余4条评论
1个回答

20

std::string::operator=(const char*)没有被&符号标记,这意味着它允许对左值和右值进行赋值操作。

有些人认为(1)赋值运算符应该被&符号标记来禁止对右值进行赋值:

(1) 例如,面向安全关键C++开发的《高完整性C++标准》中的规则12.5.7建议“使用ref-qualifier &声明赋值运算符”。(来源)

struct S {
    S& operator=(const S&) & { return *this; }
};

int main() {
    S {} = {};  // error: no viable overloaded '='
}

或者,更明确地说:

struct S {
    S& operator=(const S&) & { return *this; }
    S& operator=(const S&) && = delete;
};

int main() {
    S {} = {};  // error: overload resolution selected deleted operator '='
}

这意味着 std::string {} = "hi"; 基本上是一个空操作。提到实际行为可能仍然有价值,不仅仅是允许编写此语句的原因。 - JojOatXGME
@JojOatXGME 这取决于赋值运算符是否具有副作用,包括右侧的任何副作用。值类别不是寿命,并且当关键点是值类别时推理与生命周期相关的行为,我认为只会促进一个普遍误解,即值类别与寿命强相关。 - dfrib
我知道这点。我只是针对std::string的特定示例而言,即:“在特定情况下,例如std::string {} =“hi”;,该语句将不起作用。但是,根据构造函数,赋值运算符和可能的复制构造函数,使用std::string以外的其他类型时,这样的表达式可能会产生副作用。”无论如何,这并不是很重要。如果您认为这可能会引起误解,您可以将其保留原样。我只是觉得您基本上忽略了“它是什么意思”的部分,所以觉得有些奇怪。 - JojOatXGME

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接