4

在查看 的引用时basic_string_view,似乎缺乏(显式)用于构造 from 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)

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

4

1 回答 1

3

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

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

好的,所以......std::basic_string_view str = str_in;实际上是做什么的?好吧,它必须将任何东西转换str_inbasic_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对象,其内容将被视图引用。然后暂时的被破坏,我们的观点立即变得毫无价值。

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

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

于 2019-11-25T14:55:03.063 回答