C++ std::string s1{“现代C+;”和#x2B;”,3}vs std::string s1{str,3}
以下代码的输出使我感到困惑:C++ std::string s1{“现代C+;”和#x2B;”,3}vs std::string s1{str,3},c++,string,c++17,C++,String,C++17,以下代码的输出使我感到困惑: const std::string str = "Modern C++"; std::string s1 {"Modern C++", 3}; std::string s2 {str, 3}; std::cout << "S1: " << s1 << "\n"; std::cout << "S2: " <<
const std::string str = "Modern C++";
std::string s1 {"Modern C++", 3};
std::string s2 {str, 3};
std::cout << "S1: " << s1 << "\n";
std::cout << "S2: " << s2 << "\n";
有人能解释这个结果吗?来自:
使用以下构造函数:
basic_string( const CharT* s,
size_type count,
const Allocator& alloc = Allocator() );
basic_string( const basic_string& other,
size_type pos,
const Allocator& alloc = Allocator() );
因此需要3个字符才能获得Mod
std::string s2 {str, 3};
将使用以下构造函数:
basic_string( const CharT* s,
size_type count,
const Allocator& alloc = Allocator() );
basic_string( const basic_string& other,
size_type pos,
const Allocator& alloc = Allocator() );
因此,从位置3开始取字符串,给出:
ern C++
一个调用字符串(char const*,count)
,另一个调用字符串(string const&,pos)
一个从缓冲区中获取前3个字符,另一个从第3个字符后获取所有字符
这是因为C++有原始字符缓冲区和STD字符串。代码>“这不是std::字符串”<代码>“这是一个标准字符串”,
std::string so_is=“this”代码>
<代码> STD::String 已经超过30年了,它被添加到C++语言中,没有足够的关心(不像STL,在添加之前经过了更多的迭代)。
它的界面实在太丰富了,你可以碰到这样的东西;导致混乱结果的多个重载
谁能解释一下为什么会这样
这是因为std::string
具有它实际上不应该使用的构造函数(@ORR详细信息)。它不应该有这些构造函数,因为:
使用/std::string
方法和现有构造函数可以很容易地实现它们的效果,而不需要额外的成本(至少在C++11中),并且
仅仅从构造函数调用的角度来理解构造函数参数是如何使用的,这并不明显,也不重要
在标准库中,这不是唯一一个具有这种可拒绝(IMHO)构造函数的情况;以混淆/误导构造函数语义而闻名
生活课程:
- 吝啬建筑工人;并不是每一个用于构造类对象的常用值都应该有自己的构造函数李>
- 相反,使用
- 让您的代码审阅者或其他不太偏袒的一方阅读对构造函数的调用,以判断每一个构造函数的含义是否足够明显
如果您希望获得与
s1的Mod
s2的Mod
您可以为str使用char指针,例如
char * str = "Modern C++";
std::string s1 {"Modern C++", 3};
std::string s2 {str, 3};
std::cout << "S1: " << s1 << "\n";
std::cout << "S2: " << s2 << "\n";
你读过std::string
构造函数吗<代码>“现代C++”
不是一个std::string
,而是一个字符数组(它会自动转换为字符指针),并且有一个不同的构造函数。当然。推荐人会告诉你的。我确信这些聪明的原因是因为这些不做同样的事情,C++图书馆委员会将用完美的逻辑和推理来证明我。然而,这仅仅是一个原因——虽然小,C++标准库仍然是不直观的,甚至令人沮丧,使用。@霍利布莱克特,但是结果应该是一样的,无论如何谢谢。“惊人聪明的原因”是STD::字符串最初是几十年前设计的。因此事后看来,它的一些构造函数和功能与我们认为的现代直觉是不相称的。interface@M.M.:这一点,再加上C风格的字符串是在很久以前设计的,而且std::string
必须与它们的约定一起工作。也就是说,这两种语言可能都应该使用相同的C风格字符串语义,而不是将位置作为std::string
的有效起点和char*
的有效终点,因此您的观点仍然有效,只是要指出,这个领域的兼容性约束甚至早于std::string
。谢谢。第一个是size\u-type-count
,第二个是size\u-type-pos
。人们不得不问,为什么他们会添加两个行为如此不同的构造函数。这就像是在没有任何思想的情况下拼凑在一起。@Polygenme:“拼凑在一起根本没有思想”基本上描述了整个std::string
。它还解释了基于索引和基于迭代器的方法的混合——字符串是独立于STL开发的,然后追溯性地扩展以匹配——通常有太多“便利方法。我总是喜欢将其深入到一个由自由函数补充的最小字符串API中。这个子字符串构造函数是否有一个不会由substr
方法提供的用例?为了让它工作,第一行应该是:char str[]=“Modern C++”;或char str[]{“现代C++”};试试看,对我来说效果很好。在c++/c中,还可以用指针声明和初始化字符数组。char*str=“现代C++”;使用str[value]循环,因为str现在是一个数组。我相信没有[]的语法是char**str.char*str=“Modern C++”讽刺的是,代码C++是无效的现代C++。从C++11开始,const是必需的。(gcc)/(叮当声)
Mod
Mod