可以在构造时修改命名std::string

Possible to modify named std::string on construction?

本文关键字:std 修改 string      更新时间:2023-10-16

有人知道为什么注释行编译失败,而未注释行却可以吗?

#include <iostream>
int main()
{
    // std::string foo("hello").erase(2); // This doesn't compile...
    std::string("hello").erase(2);        // ...but this does.
}

包含注释行会导致以下错误:

main.cpp: In function ‘int main()’:
main.cpp:5: error: expected ‘,’ or ‘;’ before ‘.’ token

有人能解释一下在构建匿名和命名std::string对象的地方修改它们的规则吗?

这是一个与语言语法有关的问题。声明(一个语句)和创建临时(一个表达式)是有区别的。这两者在语言中的处理方式完全不同,并且遵循不同的规则。

声明是一个语句,您可以在其中给出变量的类型、名称和初始化该变量的表达式。例如,你可以写

std::string foo("hello");

std::string foo = "hello";

但是,不能写

std::string foo("hello").erase(2);

只是因为语言说那里不允许这种语法。我的意思是,我明白你在说什么,我想大多数人可能也会明白,但是语言规定你不允许这样做。但是,您可以写

std::string foo = std::string("hello").erase(2);

,因为声明语句允许您提供任意表达式作为初始化式。

另一方面,表达式
std::string("hello").erase(2)

作为表达式是完全格式良好的,因为表达式可以通过创建临时对象或调用不同对象的成员函数来构建。

实际上,没有理由为什么语言不能被设计成你所做的是合法的,但是不是这样设计的

创建命名的局部、全局或命名空间作用域变量的语句称为定义。定义是而不是表达式,您不能期望表达式中允许的所有内容在定义中也允许。定义严格限于初始化它所定义的对象。

第二个语句是一个表达式,因此在这里,您可以在对象上调用任何成员函数。