我并不 100% 认为以下代码在语义上是正确的:
#include <iostream>
#include <experimental/string_view>
int main()
{
std::string str = "lvalue string";
std::experimental::string_view view_lvalue(str);
std::experimental::string_view view_rvalue(std::string{"rvalue string"});
std::cout << view_lvalue << '\n' << view_rvalue << '\n';
}
Run Code Online (Sandbox Code Playgroud)
问题:我可以合法地将右值绑定到std::experimental::basic_string_view,还是只是 UB?如果是,它是如何运作的?据我所知,右值不会const通过构造函数绑定到引用(我假设视图保存原始字符串),所以我认为在语句末尾,std::experimental::string_view view_rvalue(std::string{"rvalue string"});引用将是悬空的。是否string_view使用更复杂的方法?
我问这个问题是因为我正在尝试为某些矩阵类编写类似的视图,并且还不知道如何处理右值(我当然可以禁用它们,但我认为这不是最好的方法)。
A string_view是:
一个对象,可以引用一个连续的连续序列的类似
char对象,其中序列的第一个元素位于零.典型的实现仅包含两个成员:指向常量
CharT和大小的指针.
这允许对a进行稳健但轻量级的检查string.它非常适合递归函数,否则它们将被强制使用char*s或string::iterators来削减字符串.
我的问题是其他容器呢?为什么只提供这个string?那么其他邻近容器,如vector,map,queue,等?
我需要从给定的字符串中提取特定大小的所有子字符串,然后在中查找每个子字符串std::unordered_map<string, int*>。我尝试使用此答案中的建议并用作std::less<>比较器,但编译器(gcc 8.2)抱怨以下错误。我不知道在出现错误的情况下摆弄比较器是否有意义unordered_map。
/afs/software/gcc/8.2.0/lssc0-linux/include/c++/8.2.0/bits/hashtable.h:195:21: error: static assertion failed: hash function must be invocable with an argument of key type
static_assert(__is_invocable<const _H1&, const _Key&>{}
c_counter.cpp: In function ‘void process(char*)’:
c_counter.cpp:158:27: error: no matching function for call to ‘std::unordered_map<std::__cxx11::basic_string<char>, int*, std::less<void> >::find(std::string_view&)’ if (counts->find(k) != counts->end()) {
Run Code Online (Sandbox Code Playgroud)
代码是:
std::unordered_map<std::string, int*, std::less<>> *counts = new std::unordered_map<std::string, int*, std::less<>> ;
// stuff
void prcoess(char* r) {
std::string_view seq(r) ;
for (int i = 0 ; i …Run Code Online (Sandbox Code Playgroud) 根据文档, std::string_view 有一个带有 aconst char *和 a的构造函数std::size_t,但未声明noexcept:
constexpr basic_string_view(const CharT* s, size_type count);
Run Code Online (Sandbox Code Playgroud)
另一方面,文档还声明了用户定义的文字operator""sv,在我见过的所有实现中都是该构造函数的简单包装器,已声明noexcept:
constexpr std::string_view operator "" sv(const char* str, std::size_t len) noexcept;
Run Code Online (Sandbox Code Playgroud)
你知道这种差异的原因吗?构造函数什么时候可以抛出?
我想创建一个constexpr std::array<std::string_view, ConstexprNumber>. 例如,它应该包含constexpr std::strings_view's如下内容:
"text0", "text1", "text2", ..... "textn"
我想出了以下初始解决方案:
#include <iostream>
#include <array>
#include <utility>
#include <string>
#include <string_view>
// Number of strings that we want to generate
constexpr size_t NumberOfTextsToGenerate = 10u;
// constexpr function to build a string
constexpr std::string_view makeString(unsigned int i) {
return std::string_view("text");
}
// Helper: constexpr function that will create an array of string_views and initialize it
template <unsigned int... ManyIntegers>
constexpr auto generateTextHelper(std::integer_sequence<unsigned int, ManyIntegers...>) {
return …Run Code Online (Sandbox Code Playgroud) 我最好的猜测是,委员会要么忘记了这个用例,要么不想使用概念/要求将类型限制span为可以安全散列的东西(POD,无填充),或者他们不想要半解决方案(等待反射) )...
如果有人对这里感兴趣,可以使用带有无用错误消息和代码的godbolt链接,但我认为我的问题很清楚,没有任何代码。
#include <span>
#include <unordered_set>
#include <string_view>
int main() {
std::hash<std::string_view> h1;
std::hash<std::span<char>> h2; // error here
}
Run Code Online (Sandbox Code Playgroud)
注意:我知道 C++std::库在哈希方面缺乏,例如它不能哈希std::pair<int,int>,但我的问题特别是关于std::span.
我正在尝试编写一个简单的模板函数,它接受所有可能的 basic_string_view 但我总是收到编译器错误“找不到匹配的重载函数”。
我不知道原因;调用者显式转换为 string_view 是可行的,但我想避免这种情况;还是故意变硬?
是否有扣除准则可以防止这种情况发生?
有没有一种简单的方法可以将其实现为模板?
这里(以及godbolt)是我尝试过的:
#include <string_view>
#include <string>
template <typename CharT, typename Traits> void func(std::basic_string_view<CharT, Traits> value)
//template <typename CharT> void func(std::basic_string_view<CharT> value)
//void func(std::string_view value)
{}
int main() {
std::string s;
std::string_view sv(s);
char const cs[] = "";
std::string_view csv(cs);
std::wstring ws;
std::wstring_view wsv(ws);
wchar_t const wcs[] = L"";
std::wstring_view wcsv(wcs);
func(s);
func(sv);
func(cs);
func(csv);
func(ws);
func(wsv);
func(wcs);
func(wcsv);
}
Run Code Online (Sandbox Code Playgroud)
以下是 msvc、clang 和 gcc 显示的错误:
error C2672: 'func': no matching overloaded function …Run Code Online (Sandbox Code Playgroud) 我有一个相对简单的用例:我想将一个特征关联到一个类,该类将返回一些用户定义的字符串,即一些用户定义的注册 ID。由于这个注册应该在编译时定义,我希望它是 constexpr,所以我写了如下内容:
template <typename T>
struct ClassRegistration
{
static constexpr std::string_view
Name();
};
template <>
struct ClassRegistration<int>
{
static constexpr std::string_view
Name()
{
return std::string_view{ "int" };
}
};
Run Code Online (Sandbox Code Playgroud)
一切正常,但由于 string_view 实际上并不拥有它的缓冲区,我想知道它是否保证安全,我不只是指一个悬空指针。从我读到的字符串文字保证具有与程序本身一样长的生命周期(从这个函数返回的字符串文字的SO Lifetime)。
因此,string_view 的这种用法是否安全合适?
因此,我正在阅读为较新版本的 CPP 编写的代码,并且经常看到几乎专门使用 string_view 文字,即使在简单的用例中也是如此。
例如:
std::cout<<"Hello world"sv<<std::endl;
Run Code Online (Sandbox Code Playgroud)
这有什么特别的原因吗?这显然与存储持续时间无关,因为 string_view 仅包装字符串文字。string_view 的开销是否较低?
谢谢您的宝贵时间。
我只知道C++17引入了std::string_view. 它不保存任何字符串,而是指向一个字符串。如果是这样,我对以下情况感到困惑:
std::string str = "abc";
std::string_view strV = str;
std::cout << strV << std::endl;
str = "1";
std::cout << strV << std::endl;
Run Code Online (Sandbox Code Playgroud)
我刚刚在网上的一些 c++17 编译器上尝试了这段代码,输出如下:
abc
1c
Run Code Online (Sandbox Code Playgroud)
显然,1c这不是我所期望的。
那么这是否意味着我们不应该更改分配给 a 的字符串std::string_view?