如何依据C++标准解释std::string与C字符串的条件表达式结果类型
从以下示例:
static_assert(std::same_as<decltype(true ? std::string{} : "str"), std::string>); // 编译通过
可知该条件表达式的结果是std::string类型的纯右值(prvalue),但无法依据C++标准解释这一结果。
推导可能性
#1:
第二个操作数是类类型纯右值,且无基类与派生类关系,因此适用**[expr.cond]第4.3.3款**,该条款规定目标类型(非最终结果类型)应为std::string。但该条款仅提及左值到右值、数组到指针、函数到指针的标准转换,这使得此解释存在矛盾。不过若假设std::string{}操作数确定了std::string为目标类型,且由于无法将std::string转换为const char[4](满足**[expr.cond]第4.6款**),则第三个操作数到std::string的隐式转换序列为:数组到指针转换(const char[4] -> const char*),再调用std::string接收const char*的用户定义转换构造函数。
此时不满足**[expr.cond]第5款**,因为两个操作数均为std::string纯右值,因此适用**[expr.cond]第6款**,最终推导结果为std::string类型的纯右值。
#2:
[expr.cond]第4.3.3款不适用,原因是第二个操作数为纯右值,无法进行左值到右值转换;[expr.cond]第5款也不适用,因此只能使用**[expr.cond]第6款**。但该条款指出需通过重载决议确定操作数的转换([over.match.oper]、[over.built]),而这两个条款仅涉及重载运算符和类类型到内置类型的转换函数(std::string无此类函数),似乎不包含用户定义转换构造函数,这使得此解释也不成立。不过若假设[expr.cond]第6款允许调用转换构造函数,则结果为std::string类型的纯右值。
备注
备注#1:
我所参考的标准草案中,[expr.cond]第7款仅提及数组到指针和函数到指针的标准转换;但C++20草案的同一条款还包含左值到右值转换。我好奇为何做此修改,尽管类似operator int&()的转换可能在[expr.cond]第6款中使操作数成为左值,或许能解决此问题。
备注#2:
本问题与Stack Overflow上的一个问题相关,后者的回答未提及[expr.cond]第6款中的用户定义转换,而这可能是关键细节,或许参考该问题的示例能有所帮助。
内容的提问来源于stack exchange,提问作者Sneed Deens

