扣除 string_view 的 std::make_pair 的一些奇怪行为

Posted

技术标签:

【中文标题】扣除 string_view 的 std::make_pair 的一些奇怪行为【英文标题】:some weird behavior of std::make_pair with deduction of string_view 【发布时间】:2021-01-16 03:28:23 【问题描述】:
std::string api_key_ = "123456789-5c51509f-8c5c5dc2-b6557";
std::pair<std::string_view, std::string_view> yy = std::make_pair("AccessKeyId", api_key_);
std::cout << "yy.second:" << yy.second << std::endl;

用c++17编译会输出:

yy.second:9-5c51509f-8c5c5dc2-b6557

虽然这很好,但没有扣除

std::string api_key_ = "123456789-5c51509f-8c5c5dc2-b6557";
std::string_view sv = api_key_;
std::cout << "sv:" << sv << std::endl;

std::pair<std::string_view, std::string_view> xx = std::make_pair<std::string_view, std::string_view>("AccessKeyId", api_key_);
std::cout << "xx.second:" << xx.second << std::endl;

输出:

sv:123456789-5c51509f-8c5c5dc2-b6557
xx.second:123456789-5c51509f-8c5c5dc2-b6557

谁能解释一下?谢谢。 完整代码如下:

#include <unordered_map>
#include <iostream>
#include <variant>
#include <deque>
#include <vector>

int main() 
    std::string api_key_ = "123456789-5c51509f-8c5c5dc2-b6557";
    std::string_view sv = api_key_;
    std::cout << "sv:" << sv << std::endl;

    std::pair<std::string_view, std::string_view> xx = std::make_pair<std::string_view, std::string_view>("AccessKeyId", api_key_);
    std::cout << "xx.second:" << xx.second << std::endl;

    std::pair<std::string_view, std::string_view> yy = std::make_pair("AccessKeyId", api_key_);
    std::cout << "yy.second:" << yy.second << std::endl;


编译输出:

$ g++ ./try2.cpp -std=c++17
$./a.out
sv:123456789-5c51509f-8c5c5dc2-b6557
xx.second:123456789-5c51509f-8c5c5dc2-b6557
yy.second:9-5c51509f-8c5c5dc2-b6557

【问题讨论】:

【参考方案1】:

std::make_pair("AccessKeyId", api_key_); 返回一个临时数组std::pair,其第二个元素是std::string。然后yy 从临时初始化,它的第二个元素std::string_view 是从临时std::pairstd::string 构造的(但不是api_key_)。在完整的表达式之后,临时的std::pair 被销毁,留下yy 的第二个元素持有一个悬空指针。

std::make_pair&lt;std::string_view, std::string_view&gt;("AccessKeyId", api_key_) 也返回一个临时的std::pair,但它的第二个元素是从api_key_ 构造的std::string_view。然后xx的第二个元素是从临时std::pairstd::string_view初始化并引用api_key_,这就是它有效的原因。

【讨论】:

以上是关于扣除 string_view 的 std::make_pair 的一些奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

如何将 boost::string_view 转换为 std::string_view?

除了 std::string_view 方法之外,std::string_view 比 char* 有啥优势吗?

如何在 constexpr string_view 上使用 std::string_view::remove_prefix()

惯用地拆分 string_view

在 constexpr 中连接 string_views

c++17比较string_view和string时的歧义