Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to modify named std::string on construction?

Tags:

c++

stdstring

Does anyone know why the commented line fails compilation but the uncommented line is okay?

#include <iostream>

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

Including the commented line causes this error:

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

Can someone explain what the rules are about modifying anonymous versus named std::string objects right where they are constructed?

like image 840
StoneThrow Avatar asked Sep 21 '16 00:09

StoneThrow


2 Answers

This is an issue that has to do with the syntax for the language. There's a distinction between a declaration, which is a statement, and a creation of a temporary, which is an expression. The two are handled quite differently by the language and are subject to different rules.

A declaration is a statement in which you give the type of a variable, the name, and some expression that initializes it. So, for example, you could write

std::string foo("hello");

or

std::string foo = "hello";

However, you cannot write

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

simply because the language says that that syntax isn't allowed there. I mean, I get what you're saying, and I think most people probably would as well, but the language says that you're not allowed to do that. You could, however, write

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

because declaration statements do allow you to provide arbitrary expressions as initializers.

On the other hand, the expression

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

is perfectly well-formed as an expression, because expressions can be built by creating temporary objects or calling member functions on different objects.

So really, there's no reason why the language couldn't have been designed so that what you're doing would be legal, but it just wasn't designed that way.

like image 128
templatetypedef Avatar answered Nov 06 '22 18:11

templatetypedef


The statement that creates a named local, global, or namespace-scoped variable is called a definition. A definition is not an expression, and you cannot expect that everything allowed in an expression is also allowed in a definition. A definition is strictly limited to initializing the object it defines.

The second statement is an expression, so there, you can call whatever member functions on the object you wish.

like image 5
Brian Bi Avatar answered Nov 06 '22 18:11

Brian Bi