c++ - 在 constexpr 中连接 string_views

标签 c++ c++17 constexpr string-view

我试图在 constexpr 中连接 string_views。 以下是我的代码的简化版本:

#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;test1test1;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<>如果你想做这样的事情,自定义范围作为你的返回类型。

至于您的代码产生奇怪结果的具体原因,这仅仅是因为 buffer函数退出时不再存在。

关于c++ - 在 constexpr 中连接 string_views,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47556948/

相关文章:

c++ - 通过引用将循环计数器或范围声明传递给线程有什么区别?

c++ - 有没有在 C/C++ 中定义数据类型的情况下从用户那里获取输入

C++ 最大公约数

c++ - 关于 [temp.variadic] 中包扩展的实例化的措辞

c++ - 为什么 cout() 会截断多个字符?

C++:如何从 make_shared 部分推导模板参数

c++ - 如何更新 std::vector<pair<int, int>> 中最近输入的元素?

c++ - 从动态索引中选择一个 constexpr 索引

c++ - 为什么比较 constexpr 函数的两个参数不是静态断言的常量条件?

c++ - 如果函数在类范围内声明,则 constexpr 不起作用