为什么没有string_view的推演指南?

Why is there no deduction guide for string_view?

查看basic_string_view的参考资料时,似乎缺少从std::basic_string构建的(显式)推导指南-是否重合,似乎生成了隐式推导指南对于指针类型(const char*const wchar_t*

目前我在模板中使用了以下技巧,它应该只接受任何可以粘贴到字符串视图上的内容:

using CharIn = decltype(std::basic_string(str_in))::value_type;//basicly: char or wchar_t

std::basic_string_view<CharIn> str = str_in;

我宁愿只写:

std::basic_string_view str = str_in;//<--using deduction guide (currently does not work for basic_string)

我想知道是否考虑过这个?

一般来说,您正在尝试的那种双重隐式转换是一个非常糟糕的主意,C++ 标准会竭尽所能阻止您尝试这样做。例如,过载分辨率不允许这样做;如果一个转换序列会尝试进行双重转换,它就会完全停止考虑该过载。

让我们考虑一下您的演绎指南的意图:允许 std::basic_string_view str = str_in; 适用于任何可隐式转换的类型 T,而不是某种类型的 basic_string_view,而是一个 basic_string.

好的,所以... std::basic_string_view str = str_in; 到底做了什么?好吧,它必须将任何 str_in 转换为某种形式的 basic_string。因此,要么 str_in 是一种可以调用 basic_string 的单参数构造函数的类型,要么 str_in 是一种具有重载 operator basic_string<...>.

的类型

让我们考虑一下 basic_string 的单参数构造函数。其中包括:一个用于生成空字符串的纯分配器、一个复制构造函数、一个移动构造函数、一个初始化列表构造函数,以及一个接受 const charT* 的构造函数。只有后者对这种情况有用,因此 str_in 必须是某种 charT* 类型。好吧,basic_string_view 隐式 演绎指南已经可以很好地处理这个问题。所以不需要二次转换。

所以我们现在只讨论 str_in 是具有转换运算符的类型的情况。好的:这个转换运算符 return 是 引用 basic_string 类型吗?

因为如果没有,那么 std::basic_string_view str = str_in; 将产生悬空引用。将创建一个临时 basic_string,其内容将被视图引用。然后临时对象被销毁,我们的视图立即变得一文不值。

像这样的事情就是 C++ 不喜欢双重隐式转换的原因。如果你必须输入:std::basic_string_view str = basic_string(str_in);,那么每个人都会清楚为什么你的代码被破坏了:你正在存储一个临时的视图。

如果 str_in 本身是一个字符串类型,那么最好只给它一个 operator basic_string_view 重载。