在 constexpr 中连接 string_views
concatenate string_views in constexpr
我正在尝试将 string_views
连接到 constexpr
中。
以下是我的代码的简化版本:
#include <iostream>
#include <string_view>
using namespace std::string_view_literals;
// concatenate two string_views by copying their bytes
// into a newly created buffer
constexpr const std::string_view operator+
(const std::string_view& sv1, const std::string_view& sv2)
{
char buffer[sv1.size()+sv2.size()] = {0};
for(size_t i = 0; i < sv1.size(); i++)
buffer[i] = sv1[i];
for(size_t i = sv1.size(); i < sv1.size()+sv2.size(); i++)
buffer[i] = sv2[i-sv1.size()];
return std::string_view(buffer, sv1.size()+sv2.size());
}
int main()
{
const std::string_view sv1("test1;");
const std::string_view sv2("test2;");
std::cout << sv1 << "|" << sv2 << ": " << (sv1+sv2+sv1) << std::endl;
std::cout << "test1;"sv << "|" << "test2;"sv << ": " <<
("test1;"sv+"test2;"sv) << std::endl;
return 0;
}
但是这段代码没有产生我预期的结果。它不是打印 test1;test2;test1
和 test1;test2;
,而是打印出混合了随机字符的正确字符,就好像我正在访问未初始化的内存一样。
test1;|test2;: F��<��itest;
test1;|test2;: est1;te`�i
但是,如果我删除 constexpr
说明符并将 string_views
替换为 strings
,则上面的代码会打印出预期的输出。
test1;|test2;: test1;test2;test1;
test1;|test2;: test1;test2;
要么是我的代码遗漏了一些明显的错误,要么是关于 constexpr
的某些内容我(还)不明白。这是我为新 string_view
创建缓冲区的方式吗?我还能做什么?或者我想做的事情是不可能的?也许有人可以为我阐明这一点。
您的任务根本上是不可能的,因为根据定义,string_view
需要从头到尾连续 非拥有 存储。因此将无法管理数据的生命周期。
如果您想这样做,您需要创建某种 concatenated_string<>
自定义范围作为您的 return 类型。
至于您的代码产生奇怪结果的具体原因,这仅仅是因为函数退出时 buffer
不再存在。
在 return std::string_view(buffer, sv1.size()+sv2.size());
中,返回的 string_view
查看超出范围的 buffer
,因此您实际上有一个悬空引用。
我正在尝试将 string_views
连接到 constexpr
中。
以下是我的代码的简化版本:
#include <iostream>
#include <string_view>
using namespace std::string_view_literals;
// concatenate two string_views by copying their bytes
// into a newly created buffer
constexpr const std::string_view operator+
(const std::string_view& sv1, const std::string_view& sv2)
{
char buffer[sv1.size()+sv2.size()] = {0};
for(size_t i = 0; i < sv1.size(); i++)
buffer[i] = sv1[i];
for(size_t i = sv1.size(); i < sv1.size()+sv2.size(); i++)
buffer[i] = sv2[i-sv1.size()];
return std::string_view(buffer, sv1.size()+sv2.size());
}
int main()
{
const std::string_view sv1("test1;");
const std::string_view sv2("test2;");
std::cout << sv1 << "|" << sv2 << ": " << (sv1+sv2+sv1) << std::endl;
std::cout << "test1;"sv << "|" << "test2;"sv << ": " <<
("test1;"sv+"test2;"sv) << std::endl;
return 0;
}
但是这段代码没有产生我预期的结果。它不是打印 test1;test2;test1
和 test1;test2;
,而是打印出混合了随机字符的正确字符,就好像我正在访问未初始化的内存一样。
test1;|test2;: F��<��itest;
test1;|test2;: est1;te`�i
但是,如果我删除 constexpr
说明符并将 string_views
替换为 strings
,则上面的代码会打印出预期的输出。
test1;|test2;: test1;test2;test1;
test1;|test2;: test1;test2;
要么是我的代码遗漏了一些明显的错误,要么是关于 constexpr
的某些内容我(还)不明白。这是我为新 string_view
创建缓冲区的方式吗?我还能做什么?或者我想做的事情是不可能的?也许有人可以为我阐明这一点。
您的任务根本上是不可能的,因为根据定义,string_view
需要从头到尾连续 非拥有 存储。因此将无法管理数据的生命周期。
如果您想这样做,您需要创建某种 concatenated_string<>
自定义范围作为您的 return 类型。
至于您的代码产生奇怪结果的具体原因,这仅仅是因为函数退出时 buffer
不再存在。
在 return std::string_view(buffer, sv1.size()+sv2.size());
中,返回的 string_view
查看超出范围的 buffer
,因此您实际上有一个悬空引用。