为什么没有关于string_view的推论指南?

时间:2019-11-25 12:12:51

标签: c++ language-lawyer c++17 template-meta-programming 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)

我想知道是否已经考虑过吗?

1 个答案:

答案 0 :(得分:3)

通常来说,您要进行的那种双重隐式转换是一个非常糟糕的主意,C ++标准会尽一切努力阻止您尝试这样做。例如,超载分辨率是不允许的。如果转换序列尝试进行双重转换,则完全不会考虑该过载。

让我们考虑一下您的推导指南的意图:允许std::basic_string_view str = str_in;适用于可以隐式转换的任何类型T,而不是某种类型的basic_string_view,而是一种{ {1}}。

好的,所以……basic_string的实际作用是什么?好吧,它必须将std::basic_string_view str = str_in;转换为某种str_in。因此,basic_string是可以调用str_in的单参数构造函数的类型,或者basic_string是具有重载的str_in的类型。

让我们考虑operator basic_string<...>的单参数构造函数。其中包括:仅分配器的一个用于生成空字符串的副本,一个拷贝构造器,一个move构造器,一个initializer-list构造器以及一个采用basic_string的分配器。在这种情况下,只有后一种才有用,因此const charT*必须是某种str_in类型。好吧,charT*隐式推导指南已经可以解决这个问题。因此,无需进行双重转换。

因此,我们现在仅讨论basic_string_view是具有转换运算符的类型的情况。确定:此转换运算符是否将 reference 返回为str_in类型?

因为否,basic_string将产生悬挂的参考。将创建一个临时std::basic_string_view str = str_in;,其内容将由视图引用。然后临时工被破坏了,我们的视野立即变得一文不值。

类似这样的原因就是C ++不喜欢双隐式转换的原因。如果必须键入以下内容:basic_string,那么每个人都很清楚代码为何被破坏:您正在存储临时视图。

如果std::basic_string_view str = basic_string(str_in);本身是字符串类型,那么最好给它一个str_in重载。