一般来说,您尝试的那种双重隐式转换是一个非常糟糕的主意,C++ 标准会尽其所能阻止您尝试执行它们。例如,重载解决方案不允许这样做;如果转换序列会尝试进行双重转换,它就会完全停止考虑该重载。
让我们考虑一下您的演绎指南的意图:允许std::basic_string_view str = str_in;
适用于任何T
可隐式转换的类型,而不是basic_string_view
某种类型的 a ,而是 a 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
对象,其内容将被视图引用。然后暂时的被破坏,我们的观点立即变得毫无价值。
像这样的事情就是 C++ 不喜欢双重隐式转换的原因。如果你必须输入这个:std::basic_string_view str = basic_string(str_in);
,那么每个人都会清楚你的代码为什么会被破坏:你正在存储一个临时视图。
如果str_in
它本身是一个字符串类型,那么最好只给它一个operator basic_string_view
重载。