我在弄清楚确切的语义时遇到了一些麻烦std::string.length().该文件明确指出,length()返回字符的字符串中而且数量不是字节数.我想知道在哪些情况下这实际上有所作为.
特别是,这只与非char实例化相关,std::basic_string<>或者在存储具有多字节字符的UTF-8字符串时是否也会遇到麻烦?标准是否允许length()UTF8感知?
有没有办法获得"原始"缓冲区oa std :: string?
我在想类似的东西CString::GetBuffer().例如,使用CString我会这样做:
CString myPath;
::GetCurrentDirectory(MAX_PATH+1, myPath.GetBuffer(MAX_PATH));
myPath.ReleaseBuffer();
Run Code Online (Sandbox Code Playgroud)
那么,std :: string有类似的东西吗?
我有一个声明如此的方法:
/*!
\brief Removes the leading and trailing white space from a string.
\param s The string to remove the white space from.
\param white_chars Characters to be considered as whitespace.
*/
std::string Trim(const std::string &s, const std::string &white_chars = " \t\n\r");
Run Code Online (Sandbox Code Playgroud)
该方法的定义是无趣的,但无论如何它在这里:
std::string Trim(const std::string &s, const std::string &white_chars)
{
size_t startidx = s.find_first_not_of(white_chars);
if (startidx == std::string::npos) return "";
size_t endidx = s.find_last_not_of(white_chars);
return s.substr(startidx, endidx - startidx + 1);
}
Run Code Online (Sandbox Code Playgroud)
现在在这种方法的大多数用法中,我只提供了第一个参数.Valgrind给了我以下警告
==3338== 68 bytes in 2 blocks …Run Code Online (Sandbox Code Playgroud) 无论如何都要读取已知的字节数,直接读入std :: string,而不创建临时缓冲区吗?
例如,目前我可以做到
boost::uint16_t len;
is.read((char*)&len, 2);
char *tmpStr = new char[len];
is.read(tmpStr, len);
std::string str(tmpStr, len);
delete[] tmpStr;
Run Code Online (Sandbox Code Playgroud) 我想知道我是否误解了某些内容:复制构造函数是否std::string 不复制其内容?
string str1 = "Hello World";
string str2(str1);
if(str1.c_str() == str2.c_str()) // Same pointers!
printf ("You will get into the IPC hell very soon!!");
Run Code Online (Sandbox Code Playgroud)
这将打印出"你很快就会进入IPC地狱!" 它让我烦恼
这是正常的行为std::string吗?我在某处读到它通常会做一个深层复制.
但是,这可以按预期工作:
string str3(str1.c_str());
if(str1.c_str() == str3.c_str()) // Different pointers!
printf ("You will get into the IPC hell very soon!!");
else
printf ("You are safe! This time!");
Run Code Online (Sandbox Code Playgroud)
它将内容复制到新字符串中.
我有一个指向uint8类型向量的指针.
我如何获取此指针并将向量中的数据转换为代表其内容的完整字符串?
我正在编写一些C++ 11代码,这些代码对其性质的假设std::string是有效的,但代表了在C++ 11中改变的行为.在早期,libstdc ++的basic_string实现符合98/03的要求,但不符合更严格的C++ 11要求.
据我了解,libstdc ++修复了问题basic_string.问题是人们使用的库有许多版本没有实现此修复.而且我的代码可能会以许多不愉快的方式无声地失败.
我想有一个static_assert火,如果用户尝试编译我的图书馆对的libstdc ++的那些不符合的版本.如何检测版本,同样重要的是,我应该查找哪个版本?
我们每个人(可能)都有童年的写作梦想:
switch(my_std_string) {
case "foo": do_stuff(); break;
case "bar": do_other_stuff(); break;
default: just_give_up();
}
Run Code Online (Sandbox Code Playgroud)
但这是不可能的,正如古代(2009年)对这个问题的答案所解释的那样:
从那时起,我们已经看到了C++ 11的出现,它让我们走得更远:
switch (my_hash::hash(my_std_string)) {
case "foo"_hash: do_stuff(); break;
case "bar"_hash: do_other_stuff(); break;
default: just_give_up();
}
Run Code Online (Sandbox Code Playgroud)
如在描述答案来编译时间字符串哈希 -这是没有那么糟糕,但它实际上并没有做正是我们想要的-有碰撞的机会.
我的问题是:从那时起语言的发展(我认为主要是C++ 14)是否影响了编写一个字符串case语句的方式?或简化实现上述目的的螺母和螺栓?
具体而言,与结束C++ 17标准之中指日可待 -我很感兴趣,鉴于我们可以假设标准将包含答案.
注意:这不是关于使用switch语句的优点的讨论,也不是关于meta的线程的讨论.我问的是一个内容丰富的问题,所以请在此基础上回答/ up/downvote.
许多开发人员和库作者已经在编译时字符串方面苦苦挣扎了好几年了,因为标准(库)字符串std::string需要动态分配内存,而不是constexpr。
因此,关于如何正确获取编译时字符串,我们有很多问题和博客文章:
现在我们已经了解到,不仅代码new可用constexpr,可以在编译时进行动态分配,而且实际上,std::string它将在C ++ 20(Herb Sutter的C ++标准工作组会议报告)中成为constexpr。
这是否意味着对于C ++ 20及以上版本的代码,我们应该放弃所有这些漂亮的编译时字符串实现,并且始终使用std::string?
如果不是,我们什么时候会这样做,什么时候我们会坚持今天的可能(当然不是向后兼容的代码)?
注意:我不是在谈论内容是其类型一部分的字符串,即不是在谈论std::integral_constant; 的等价形式。绝对不会std::string。
以下代码给出了悬空指针错误。
std::vector<std::pair<std::string, int>> c;
for (auto& b : c) {
const auto& [s, i] = b;
std::string_view v = s.substr(i);
std::cout << v;
}
Run Code Online (Sandbox Code Playgroud)
我认为它b保存了对 的引用std::pair<std::string, int>,所以s应该是对pair对象中字符串的引用。为什么这会产生悬空指针错误?我在这里缺少什么?godbolt 链接: https: //godbolt.org/z/4zMvbr