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

Sto*_*row 5 c++ stdstring

有谁知道为什么注释行无法编译,但未注释的行是好的?

#include <iostream>

int main()
{
    // std::string foo("hello").erase(2); // This doesn't compile...
    std::string("hello").erase(2);        // ...but this does.
}
Run Code Online (Sandbox Code Playgroud)

包括注释行会导致此错误:

main.cpp: In function ‘int main()’:
main.cpp:5: error: expected ‘,’ or ‘;’ before ‘.’ token
Run Code Online (Sandbox Code Playgroud)

有人可以解释std::string在构造它们的地方修改匿名对象和命名对象的规则是什么吗?

tem*_*def 8

这是一个与语言语法有关的问题.声明(一种声明)与临时创建(表达式)之间存在区别.这两种语言的处理方式完全不同,并受到不同规则的约束.

声明是一种语句,您可以在其中提供变量的类型,名称以及初始化它的表达式.所以,例如,你可以写

std::string foo("hello");
Run Code Online (Sandbox Code Playgroud)

要么

std::string foo = "hello";
Run Code Online (Sandbox Code Playgroud)

但是,你不能写

std::string foo("hello").erase(2);
Run Code Online (Sandbox Code Playgroud)

只是因为语言说那里不允许那种语法.我的意思是,得到你所说的,我认为大多数人可能也会这样,但语言说你不允许这样做.但是,你可以写

std::string foo = std::string("hello").erase(2);
Run Code Online (Sandbox Code Playgroud)

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

另一方面,表达

std::string("hello").erase(2)
Run Code Online (Sandbox Code Playgroud)

表达式是完美的,因为表达式可以通过创建临时对象或在不同对象上调用成员函数来构建.

所以真的,有没有理由的语言不能被设计让你在做什么是合法的,但它只是没有这样设计的.


Bri*_*ian 5

创建命名的本地,全局或命名空间范围变量的语句称为定义.定义不是表达式,您不能指望在定义中也允许表达式中允许的所有内容.定义严格限于初始化它定义的对象.

第二个语句是一个表达式,所以在那里,你可以调用你想要的对象上的任何成员函数.