微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 这两个添加字符串的情况有什么区别?

我注意到,当我初始化一个字符串时,编译器报告了一个我没想到的错误.

例如:

#include <iostream>
#include <string>

using namespace std;

int main() {
    string s1 = "Hello",s2 = "World!"; // ok
    string s3 = s1 + "," + "World!"; // ok
    string s4 = "Hello" + "," + s2; // error
    cout << s1 + " " + s2 << endl; //ok
    return 0;
}

对我来说,如果s3工作正常,s4也应该这样做.

为什么我会收到这个错误?这两个初始化字符串(s3和s4)之间有什么区别?

解决方法

“Hello”不是std :: string(而是它是一个const char [6],而“,”是一个const char [3])并且std :: strings的运算符不适用.

这是C的一个小小的不便,源于它的C系列.这意味着在连接字符串时必须确保它的两个操作数中至少有一个实际上是一个std :: string,如

auto s = std::string{"Hello"} + "," + "World";

其中第一个一个std :: string作为它的第一个操作数,因此产生一个std :: string,所以第二个也有一个std :: string作为它的第一个操作数(因为从左到右处理).

T.C.的注释提示的Edit1,我提到如果只用空格分隔,C字符串文字自动连接

std::string s = "Hello" "," "World";

此行为也是从C继承的:预处理器将上面的代码呈现给

std::string s = "Hello,World";

在编译器正确处理它之前(更准确地说,字符串连接发生在翻译的phase 6,就在编译之前).这实际上是连接原始字符串文字的最简单,也是最方便的方法.但请注意,我必须声明s的类型,因为自动推断会给出一个const char *.

PaperBirdMaster评论提示的Edit2中,我提到自从C 14以来,如果你拉入相关的operator""s(或周围的命名空间),你可以直接在字符串之后添加s来直接形成std :: string文字.

using std::literals::operator""s;                // pull in required operator
const auto s = "Hello"s + "," + "World";        // std::string

请参阅this post,了解为什么必需的运算符“”隐藏在嵌套的命名空间中.另请注意,使用std :: literals :: operator“”;你可以拉入周围的命名空间:以下任何一个声明都可以.

using namespace std::string_literals;
using namespace std::literals::string_literals;
using namespace std::literals;

使用命名空间std;并没有那么糟糕(和该死)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐