c++ - `a ? b : c`是什么类型?

标签 c++

假设我们有

template <typename T>
struct Foo
{};


struct Bar
{
    template <typename T>
    operator Foo<T>() const { return Foo<T>(); }
};


template <typename T>
Foo<T> Baz(T const&) { return Foo<T>(); }

然后,true ? Bar() : Baz(some_expr_of_type_double)的类型为Foo<double>,因为Bar可转换为Foo<double>。此技巧用于查询some_expr_of_type_double的类型而不对其进行评估。

确定a ? b : c类型的规则是什么?我会很感激该标准的相关部分(我没有拷贝)。除了“typeof(b)必须可以明确转换为typeof(c)或反之亦然”之外,还有其他吗?

最佳答案

这是相关的规范:

5.16条件运算符[expr.cond]

  • 条件表达式组
    右到左。第一个表达
    隐式转换为 bool
    (第4节)。它被评估,如果
    这是真的,
    条件表达式就是值(value)
    第二个表达式的值,否则
    第三个表达式的值。全部
    第一个表达式的副作用
    除了销毁
    临时(12.2)发生在
    第二或第三个表达式是
    评估。只有第二个
    然后评估第三个表达式。
  • 如果第二个或第三个操作数具有类型(可能是cv限定)的void,则从左值到右值(4.1),数组到指针(4.2)和函数到指针(4.3)标准转换在第二个和第三个操作数上执行,并且下列条件之一应成立:

    —第二个或第三个操作数(但不是两个)都是throw-expression(15.1);结果是另一个的类型,并且是一个右值。

    —第二和第三操作数的类型均为void;结果是void类型,是一个右值。

    [注意:这包括两个操作数均为throw-expressions的情况。 ]
  • 否则,如果第二个操作数和第三个操作数具有不同的类型,并且两者都具有(可能是cv限定的)类类型,则尝试将这些操作数中的每个转换为另一个操作数。确定是否可以将类型T1的操作数表达式E1转换为匹配类型T2的操作数表达式E2的过程定义如下:

    3.a:如果E2是左值:如果可以将E1隐式转换为“对T2的引用”类型,则可以将E1转换为与E2匹配,但要满足以下条件:在转换中,引用必须直接绑定(bind)( 8.5.3)至E1。

    3.b:如果E2是右值,或者上述转换无法完成:

    3.b.1:如果E1和E2具有类类型,并且基础类类型相同,或者一个是另一个的基类:如果T2的类与以下类型相同,则可以将E1转换为匹配E2, T1的类别或T1的基本类别,并且T2的cv限定与t1的cv限定相同,或者具有比T1的cv限定更大的cv限定。如果应用了转换,则将E1更改为类型T2的右值,该值仍然引用原始源类对象(或其适当的子对象)。 (注意:也就是说,不进行任何复制。)

    3.b.2:否则(即,如果E1或E2具有非类类型,或者它们都具有类类型,但基础类既不相同又不是另一个的基类):可以将E1转换为如果可以将E1隐式转换为表达式E2,如果将E2转换为右值(或者如果E2是右值,则具有它的类型),则匹配E2。

    使用此过程,确定是否可以将第二操作数转换为与第三操作数匹配,以及是否可以将第三操作数转换为与第二操作数匹配。如果两者都可以转换,或者一个都可以转换但转换不明确,则说明程序格式错误。如果两个都不能转换,则操作数保持不变,并按如下所述进行进一步检查。如果仅可能进行一次转换,则将该转换应用于所选的操作数,并且在本节的其余部分中,将使用转换后的操作数代替原始操作数。
  • 如果第二个和第三个操作数是左值并且具有相同的类型,则结果是该类型并且是左值。
  • 否则,结果为右值。如果第二个和第三个操作数不具有相同的类型,并且都具有(可能是cv限定的)类类型,则使用重载解析来确定要应用于这些操作数的转换(如果有)(13.3.1.2、13.6) 。如果重载解析失败,则程序格式错误。否则,将应用由此确定的转换,并在本节的其余部分中使用转换后的操作数代替原始操作数。
  • 对第二和第三个操作数执行左值到右值(4.1),数组到指针(4.2)和函数到指针(4.3)的标准转换。进行这些转换后,应满足以下条件之一:

    6.a:第二和第三操作数具有相同的类型;结果就是这种类型。

    6.b:第二和第三操作数具有算术或枚举类型;通常的算术转换将其转换为通用类型,结果就是该类型。

    6.c:第二和第三操作数具有指针类型,或者一个具有指针类型,另一个是空指针常量;执行指针转换(4.10)和资格转换(4.4),以将其转换为复合指针类型(5.9)。结果是复合指针类型。

    6.d:第二和第三操作数具有指向成员类型的指针,或者一个具有指向成员类型的指针,另一个是空指针常量;执行指向成员转换(4.11)和限定转换(4.4)的指针,以将它们转换为通用类型,其cv-qualification应与第二或第三个操作数的cvqualification相匹配。结果是普通类型的。
  • 关于c++ - `a ? b : c`是什么类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4149335/

    相关文章:

    C++ 静态函数和线程安全

    c++ - 图像格式和无符号字符数组

    c++ - 检索从中实例化类型的模板

    c++ - 按值或 C++11 通用引用传递仿函数?

    c++ - 如何在 C++ 中防止/抑制 SIGFPE?

    c++ - 寻线器 OpenCV

    c++ - 模板参数数量错误

    c++在类之间传递指针 - 访问其他类方法

    c++ - C memset 似乎没有写给每个成员

    c++ - ALSA 捕获丢失的帧