在查看 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/