为什么没有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
重载。
查看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
重载。