一般来说,您尝试的那种双重隐式转换是一个非常糟糕的主意,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重载。