连接两个字符串文字

发布于 2024-11-08 15:29:29 字数 514 浏览 5 评论 0原文

我正在阅读 Koenig 的 Accelerated C++。他写道,“新的想法是,我们可以使用 + 连接一个字符串和一个字符串文字 - 或者,就此而言,两个字符串(但不是两个字符串文字)。

好吧,我认为这是有道理的。现在到两个单独的练习旨在阐明这

一点

const string hello = "Hello";

const string message = hello + ",world" + "!";

。现在,我尝试执行上面的内容并且它起作用了!

然后我尝试做下一个练习;

const string exclam = "!";

const string message = "Hello" + ",world" + exclam;

现在我明白它有问题。无法连接两个字符串这一事实文字,但我不明白为什么我设法让第一个示例工作(不是“,world”和“!”两个字符串文字吗?这不应该起作用吗?)之间的语义差异,但不是第二。

I am reading Accelerated C++ by Koenig. He writes that "the new idea is that we can use + to concatenate a string and a string literal - or, for that matter, two strings (but not two string literals).

Fine, this makes sense I suppose. Now onto two separate exercises meant to illuminate this .

Are the following definitions valid?

const string hello = "Hello";

const string message = hello + ",world" + "!";

Now, I tried to execute the above and it worked! So I was happy.

Then I tried to do the next exercise;

const string exclam = "!";

const string message = "Hello" + ",world" + exclam;

This did not work. Now I understand it has something to do with the fact that you cannot concatenate two string literals, but I don't understand the semantic difference between why I managed to get the first example to work (isn't ",world" and "!" two string literals? Shouldn't this not have worked?) but not the second.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

情域 2024-11-15 15:29:29
const string message = "Hello" + ",world" + exclam;

+ 运算符具有从左到右的关联性,因此等效的括号表达式为:

const string message = (("Hello" + ",world") + exclam);

如您所见,两个字符串文字 "Hello"", world” 首先“添加”,因此出现错误。

连接的前两个字符串之一必须是 std::string 对象:

const string message = string("Hello") + ",world" + exclam;

或者,您可以通过将表达式的该部分括起来来强制首先计算第二个 +

const string message = "Hello" + (",world" + exclam);

您的第一个示例 (hello + ",world" + "!") 有效是有道理的,因为 std::string (hello ) 是最左边的 + 的参数之一。对 + 进行求值,结果是一个带有连接字符串的 std::string 对象,然后将生成的 std::string 连接起来与“!”


至于为什么不能使用+连接两个字符串文字,这是因为字符串文字只是一个字符数组(一个const char [N] 其中 N 是字符串的长度加一(对于空终止符)。当您在大多数上下文中使用数组时,它会转换为指向其初始元素的指针。

因此,当您尝试执行 "Hello" + ",world" 时,您真正想做的是将两个 const char* 添加在一起,这不是'不可能(将两个指针加在一起意味着什么?),如果是的话,它不会做你想要它做的事情。


请注意,您可以通过将字符串文字并排放置来连接它们;例如,以下两个是等效的:

"Hello" ",world"
"Hello,world"

如果您有一个很长的字符串文字,并且想要将其分成多行,则这非常有用。不过,它们必须是字符串文字:这不适用于 const char* 指针或 const char[N] 数组。

const string message = "Hello" + ",world" + exclam;

The + operator has left-to-right associativity, so the equivalent parenthesized expression is:

const string message = (("Hello" + ",world") + exclam);

As you can see, the two string literals "Hello" and ",world" are "added" first, hence the error.

One of the first two strings being concatenated must be a std::string object:

const string message = string("Hello") + ",world" + exclam;

Alternatively, you can force the second + to be evaluated first by parenthesizing that part of the expression:

const string message = "Hello" + (",world" + exclam);

It makes sense that your first example (hello + ",world" + "!") works because the std::string (hello) is one of the arguments to the leftmost +. That + is evaluated, the result is a std::string object with the concatenated string, and that resulting std::string is then concatenated with the "!".


As for why you can't concatenate two string literals using +, it is because a string literal is just an array of characters (a const char [N] where N is the length of the string plus one, for the null terminator). When you use an array in most contexts, it is converted into a pointer to its initial element.

So, when you try to do "Hello" + ",world", what you're really trying to do is add two const char*s together, which isn't possible (what would it mean to add two pointers together?) and if it was it wouldn't do what you wanted it to do.


Note that you can concatenate string literals by placing them next to each other; for example, the following two are equivalent:

"Hello" ",world"
"Hello,world"

This is useful if you have a long string literal that you want to break up onto multiple lines. They have to be string literals, though: this won't work with const char* pointers or const char[N] arrays.

徒留西风 2024-11-15 15:29:29

从 C++14 开始,您可以使用两个真实的 字符串文字

const string hello = "Hello"s;

const string message = hello + ",world"s + "!"s;

const string exclam = "!"s;

const string message = "Hello"s + ",world"s + exclam;

Since C++14 you can use two real string literals:

const string hello = "Hello"s;

const string message = hello + ",world"s + "!"s;

or

const string exclam = "!"s;

const string message = "Hello"s + ",world"s + exclam;
究竟谁懂我的在乎 2024-11-15 15:29:29

您应该始终注意类型

虽然它们看起来都像字符串,但 "Hello"",world"文字

在您的示例中,exclam 是一个std::string 对象。

C++ 有一个运算符重载,它接受一个 std::string 对象并向其中添加另一个字符串。当您将 std::string 对象与文字连接时,它将对该文字进行适当的转换。

但是,如果您尝试连接两个文字,编译器将无法找到采用两个文字的运算符。

You should always pay attention to types.

Although they all seem like strings, "Hello" and ",world" are literals.

And in your example, exclam is a std::string object.

C++ has an operator overload that takes a std::string object and adds another string to it. When you concatenate a std::string object with a literal it will make the appropriate casting for the literal.

But if you try to concatenate two literals, the compiler won't be able to find an operator that takes two literals.

述情 2024-11-15 15:29:29

您的第二个示例不起作用,因为两个字符串文字没有 operator + 。请注意,字符串文字不是 string 类型,而是 const char * 类型。如果您像这样修改它,您的第二个示例将起作用:

const string message = string("Hello") + ",world" + exclam;

Your second example does not work because there is no operator + for two string literals. Note that a string literal is not of type string, but instead is of type const char *. Your second example will work if you revise it like this:

const string message = string("Hello") + ",world" + exclam;
心清如水 2024-11-15 15:29:29

字符串(或者准确地说,std::string)和字符文字之间的区别在于,后者没有定义 + 运算符。这就是第二个例子失败的原因。

在第一种情况下,编译器可以找到合适的operator+,其中第一个参数是string,第二个参数是字符文字(const char* )所以它使用了它。该操作的结果又是一个字符串,因此在向其中添加"!" 时会重复相同的技巧。

The difference between a string (or to be precise, std::string) and a character literal is that for the latter there is no + operator defined. This is why the second example fails.

In the first case, the compiler can find a suitable operator+ with the first argument being a string and the second a character literal (const char*) so it used that. The result of that operation is again a string, so it repeats the same trick when adding "!" to it.

初雪 2024-11-15 15:29:29

在情况 1 中,由于操作顺序,您得到:

(hello + ", world") + "!"解析为 hello + "!"最后是 hello

在情况 2 中,正如 James 指出的,您将得到:

("Hello" + ", world") + exclam,这是 2 个字符串文字的连接。

希望很清楚:)

In case 1, because of order of operations you get:

(hello + ", world") + "!" which resolves to hello + "!" and finally to hello

In case 2, as James noted, you get:

("Hello" + ", world") + exclam which is the concat of 2 string literals.

Hope it's clear :)

旧城空念 2024-11-15 15:29:29

如果我们写
字符串 s = "你好" + "世界!";
RHS 有以下类型
const char [6] + const char [7]

现在两者都是内置数据类型。
即,它们不再是 std::string 类型。

所以,现在内置类型的运算符重载
由编译器定义适用。
即 - 不再有 std::string 重载的运算符 +。

现在让我们看看编译器如何

  • 为两个 const char * 类型的操作数重载二元运算符。

事实证明,编译器在这种情况下没有重载,因为它的意义较小。

即,添加两个“const char *”在语义上是错误的,因为结果在运行时将是另一个 const char *。
可能有很多原因导致上述内容没有意义。

因此,总的来说,任何运算符重载都有一个通用规则。这是 :
当该运算符的所有操作数仅是内置时重载该运算符。编译器设计者会考虑这种情况。在我们确切的问题中,由于这条规则, std::string 不能重载两个“const 文字”,并且编译器选择不实现 + 二元运算符,因为它毫无意义。

如果我们喜欢字符串文字形式,我们可以使用“s”运算符,如下所示。
std::string p = "hello"s + "world!"s;

只是加上s后缀,意思就变了。
(s 重载运算符)

if we write
string s = "hello" + "world!";
RHS has following type
const char [6] + const char [7]

Now both are built in data types.
ie, they are not std::string types any more.

So, now operator overloading of built in types
as defined by compiler applies.
ie - no more operator + overloaded by std::string.

now let us turn to how compiler overloads

  • binary operator for two operands of const char * type.

it turns out, compiler did not overload for this case, as it is meaning less.

ie, adding two 'const char *' is semantically wrong as result would be another const char * in run time.
There can be many reason why above does not make sense.

Hence over all, there is one generic rule for any operator overloading. it is :
overloading any operator when all operands of that operator are built-in only. Compiler designers would take of such cases. In our exact question, std::string can't overload two 'const literals' because of this rule, and compiler choose to not to implement the + binary operator for its meaninglessness.

if we like the string literal form and we can a "s" operator as below.
std::string p = "hello"s + "world!"s;

just suffix with s, the meaning changes.
(s overloaded operator)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文