C++ 当在cv非限定非数组对象类型的两个xvalues上使用时,条件运算符能否生成cv限定、数组或函数类型?

C++ 当在cv非限定非数组对象类型的两个xvalues上使用时,条件运算符能否生成cv限定、数组或函数类型?,c++,language-lawyer,C++,Language Lawyer,给定两种非数组对象类型T1和T2,表达式是否为真?std::declval():std::declval()是否有cv限定、数组或函数类型?我很确定这不可能,但我想确保我没有忽略任何事情 动机:当前提议的解析不会衰减形式为true的条件表达式的类型?std::declval():std::declval(),其中D1和D2由std::decay生成(因此是cv不合格的非数组对象类型*)。仅当条件表达式的类型衰减无效时(如果类型为cv限定、数组或函数类型**,则不正确),此选项才正确 *忽略“异

给定两种非数组对象类型
T1
T2
,表达式
是否为真?std::declval():std::declval()
是否有cv限定、数组或函数类型?我很确定这不可能,但我想确保我没有忽略任何事情


动机:当前提议的解析不会衰减形式为
true的条件表达式的类型?std::declval():std::declval()
,其中
D1
D2
std::decay
生成(因此是cv不合格的非数组对象类型*)。仅当条件表达式的类型衰减无效时(如果类型为cv限定、数组或函数类型**,则不正确),此选项才正确

*忽略“异常函数类型”案例(无论如何都不会生成有效表达式)和
void
案例(这是一个单独的问题)。
**根据,表达式从来没有引用类型。

我们可以使用以下方法证明这一点:

  • 如果第二个或第三个操作数的类型为
    void
    ,[…]
  • 第一个子项目符号将抛出表达式作为操作数,第二个子项目符号给出结果类型
    void

  • 否则,如果第二个和第三个操作数是相同值类别且类型为cv1的glvalue位字段
    T
    和cv2
    T
    ,在本节的其余部分,操作数被视为cv
    T
    类型, 其中,cv是cv1和cv2的并集
  • 空集合的并集是空的,所以这里没有什么可担心的

  • 否则,如果第二个和第三个操作数具有不同的类型,并且其中一个具有(可能是cv限定的)类 类型,或者如果两者都是相同值类别和相同类型(cv鉴定除外)的GLV值,则 尝试从这些操作数中的每一个到类型的隐式转换序列(13.3.3.1) 另一个
  • 让我们分析以下每种情况:

    • (4.1)如果
      E2
      是左值,目标类型是“对
      T2
      的左值引用”
      ,[…]
    • (4.2)如果
      E2
      是一个x值,目标类型是“对
      T2
      的右值引用”
      ,[…]
    因此,表达式的类型为
    T2
    ,cv不符合假设

    • (4.3)如果
      E2
      是prvalue,或者如果上述两个转换序列都无法形成,并且至少一个操作数具有(可能是cv限定的)类类型:
      • 如果
        T1
        T2
        是相同的类类型(忽略cv限定),或者其中一个是另一个的基类,并且
        T2
        至少与
        T1
        具有相同的cv限定,则目标类型为
        T2
      • 否则,目标类型是将左值应用于右值(4.1)、数组应用于指针(4.2)和函数应用于指针(4.3)标准转换后,
        E2
        将具有的类型
    在第一种情况下,目标类型是假设不合格的cv


    最后,l-t-r转换不会添加cv限定()。和*-到指针的转换也不能做到这一点;事实上,它们在应用程序之后生成的是指针(即非数组、非类)类型的prvalue,根据,它永远不会被cv限定。由于
    E2
    属于
    T2
    类型,因此在这种情况下,目标类型也是cv不合格的。

    有趣的事实:72%的问题标题需要至少三次解析。我本来希望通过调用转换函数并获得双方的联合cv资格,得到
    常量A
    ,但显然,它将转换函数结果复制到一个新的
    对象中。或者它去掉了
    常量
    ,我认为它不会这样做,因为这是不安全的。验证:它将返回值复制到一个新的临时值:…并且[expr.cond]/6重载解析也不会导致增加cv限定(并且在任何情况下,只产生标量类型,因此任何假设的cv资格立即被[expr.cond]/7中的l-t-r剥离)。