在查看 basic_string_view 的引用时,似乎缺少从 std::basic_string 构造的(显式)推导指南 - 无论是否一致,似乎为指针类型( const char*const wchar_t* )生成了隐式推导指南

目前,我在模板中采用以下 技巧 ,该模板应该只接受任何可以卡在字符串 View 上的内容:

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 是具有转换运算符的类型的情况。好的:这个转换运算符是否返回对 basic_string 类型的引用?

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

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

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

关于c++ - 为什么string_view没有推导指南?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59031588/

10-12 17:55