说真的,什么都没有.有从隐式转换std::string到std::string_view,它不是认为是不安全的.如果程序员不小心,这肯定会导致许多悬空引用.
在另一方面,他们已经解雇的隐式转换从std::string_view到std::string使用相同的说法,但在完全相反的方式:因为程序员可能是不小心的.
很可爱的是,他们创建了一个原始const char*指针的替代品,同时使它变得非常混乱并剥离了骨头:
const char*- > std::string:好的std::string_view- > std::string:NOPEstd::string= const char*:好的std::string= std::string_view:好的std::string+ = const char*:好的std::string+ = std::string_view:好的const char*+ std::string:好的std::string_view+ std::string:NOPEstd::string+ const char*:好的以下代码不能在 C++20 中编译
#include <iostream>
#include <cstddef>
int main(){
std::byte b {65};
std::cout<<"byte: "<<b<<'\n';// Missing overload
}
Run Code Online (Sandbox Code Playgroud)
std::byteC++17什么时候加入的,为什么没有对应的operator<<重载打印呢?我也许可以理解不打印容器的选择,但为什么不std::byte呢?它试图充当原始类型,我们甚至有 的重载std::string,最近的std::string_view,也许是最相关的 std::complex,并且std::bitset它本身可以被打印。
还有std::hex类似的修饰符,所以默认打印 0-255 应该不是问题。
这只是疏忽吗?怎么样operator>>,std::bitset有它,它根本不是微不足道的。
编辑:发现甚至std::bitset可以打印。
我们的团队正在使用具有10多年历史的C ++代码库,并且最近切换到了C ++ 17编译器。因此,我们正在寻找使代码现代化的方法。在YouTube的一次会议演讲中,我听到了用替换const char*全局字符串的建议constexpr string_view。
由于我们的代码中有很多这样的const char*全局字符串常量,因此我想问一下是否需要了解一些陷阱或潜在问题?
我是 C++17 和std::string_view. 我了解到它们不是空终止的,必须小心处理。
这是 printf() 的正确方法吗?
#include<string_view>
#include<cstdio>
int main()
{
std::string_view sv{"Hallo!"};
printf("=%*s=\n", static_cast<int>(sv.length()), sv.data());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
(或者将它与任何其他 printf 风格的函数一起使用?)
我发现新C++ 17标准的string_view有点多余.
我们有一个非常详细的简单机制集合,用于将数据传递给被调用者,没有太多开销,现在又有一个也只针对一种容器类型.
我不明白为什么只为字符串提供这种机器而不是为其他容器提供更普遍的类型.一个明智的答案是我们已经有了这些解决方案.例如,在C++ 17及更高版本中,演示文稿string_view被解释为observer_ptr<T> (or T*) for string.
与C++ 17引入的string_view相比,请说明针对更通用的container_view的参数.
我的问题是由stackoverflow上的这个答案激发的,/sf/answers/3365740731/.报价,
问:你如何转换
std::string_view为const char*?答:只需做一个
std::string(string_view_object).c_str()获得保证的以空值终止的临时副本(并在行尾清理它).
不幸的是,它构建了一个新的string.我想知道是否可以做到,
static_cast<string>(string_view_object).c_str()
Run Code Online (Sandbox Code Playgroud)
现在,我的问题是:
这会构造一个新字符串吗?
是否保证返回以null结尾的char序列?
我有一小段代码用于演示.它似乎工作正常.(参见wandbox 结果)
#include <string>
#include <iostream>
#include <string_view>
#include <cstring>
int main()
{
std::string str{"0123456789"};
std::string_view sv(str.c_str(), 5);
std::cout << sv << std::endl;
std::cout << static_cast<std::string>(sv) << std::endl;
std::cout << strlen(static_cast<std::string>(sv).c_str()) << std::endl;
}
Run Code Online (Sandbox Code Playgroud) 以下代码给出了悬空指针错误。
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
我想消除代码中对 #define 宏的依赖,但我无法使用constexpr.
为了实用,请考虑以下示例:
\n#define PRODUCT_NAME "CloysterHPC"\nconstexpr const char* productName = PRODUCT_NAME;\n\nclass Newt : public View {\nprivate:\n struct TUIText {\n\n#if __cpp_lib_constexpr_string >= 201907L\n static constexpr const char* title =\n fmt::format("{} Installer", productName).data();\n#else\n static constexpr const char* title = PRODUCT_NAME " Installer";\n#endif\n\n };\n};\nRun Code Online (Sandbox Code Playgroud)\n我经历了惨痛的教训才知道fmt::format()函数不是constexpr函数,它只是一个运行时函数。我本以为我可以在代码中更具表现力,但我不能。所以我尝试使用std::string,但在将代码更改为类似以下内容后,我再次得到了相同的确切结果:
#define PRODUCT_NAME "CloysterHPC"\nconstexpr const char* productName = PRODUCT_NAME;\n\nclass Newt : public View {\nprivate:\n struct TUIText {\n\n#if __cpp_lib_constexpr_string >= 201907L\n static constexpr const char* title = …Run Code Online (Sandbox Code Playgroud) Boost提供了两种不同的实现string_view,它们将成为C++ 17的一部分:
boost::string_ref 在 utility/string_ref.hppboost::string_view 在 core/string_view.hpp这些之间有什么重大差异吗?哪个应该是首选的?
注意:我注意到在Boost 1.61中,boost :: log已经弃用了string_ref而支持string_view; 也许这是一个指标?(http://www.boost.org/users/history/version_1_61_0.html)
我有一堂课:
class Symbol_t {
public:
Symbol_t( const char* rawName ) {
memcpy( m_V, rawName, 6 * sizeof( char ) );
};
string_view strVw() const {
return string_view( m_V, 6 );
};
private:
char m_V[6];
}; // class Symbol_t
Run Code Online (Sandbox Code Playgroud)
并且有一个我无法修改的 lib-func:
extern bool loadData( const string& strSymbol );
Run Code Online (Sandbox Code Playgroud)
如果有局部变量:
Symbol_t symbol( "123456" );
Run Code Online (Sandbox Code Playgroud)
当我需要调用loadData时,我不敢这样做:
loadData( string( symbol.strVw().begin(), symbol.strVw().end() ) );
Run Code Online (Sandbox Code Playgroud)
我必须这样做:
string_view svwSym = symbol.strVw();
loadData( string( svw.begin(), svw.end() ) );
Run Code Online (Sandbox Code Playgroud)
我的问题:第一种方法正确吗?还是我必须使用第二个?
因为我认为在方法 1 中,我传递给 std::string 的构造函数的迭代器是两个不同的 string_vew 对象,理论上结果是未定义的,即使我们几乎所有的 C++ 编译器都会得到预期的结果。 …