让我们说我们有
template <typename T>
struct Foo
{};
Run Code Online (Sandbox Code Playgroud)
和
struct Bar
{
template <typename T>
operator Foo<T>() const { return Foo<T>(); }
};
Run Code Online (Sandbox Code Playgroud)
和
template <typename T>
Foo<T> Baz(T const&) { return Foo<T>(); }
Run Code Online (Sandbox Code Playgroud)
然后,因为可以转换为true ? Bar() : Baz(some_expr_of_type_double)类型.此技巧用于查询类型而不进行评估.Foo<double>BarFoo<double>some_expr_of_type_double
确定类型的规则是a ? b : c什么?我很欣赏标准的相关部分(我没有副本).有没有" typeof(b)必须可以转换为typeof(c),反之亦然,毫不含糊"?
以下是相关规范:
\n\n条件表达式\n从右到左分组。第一个表达式\n 隐式转换为bool\n(第4 条)。对其进行求值,如果\n为 true,\n条件表达式的结果\n为第二个表达式的值,\n否则为第三个表达式的值。\n第一个表达式的所有副作用(临时变量 (12.2) 的破坏除外)\n都发生在对\n第二个或第三个表达式求值之前。仅计算第二个\n和第三个表达式之一。
如果第二个或第三个操作数的类型(可能是 cv 限定的)void,则左值到右值 (4.1)、数组到指针 (4.2) 和函数到指针 (4.3) 标准转换为对第二个和第三个操作数执行,并且以下之一应成立:
\n\n\xe2\x80\x94 第二个或第三个操作数(但不是两者)是一个 throw 表达式 (15.1);结果是另一个的类型并且是右值。
\n\n\xe2\x80\x94 第二个和第三个操作数的类型均为 void;结果是 void 类型并且是右值。
\n\n[注意:这包括两个操作数都是 throw 表达式的情况。]
否则,如果第二个和第三个操作数具有不同的类型,并且其中一个具有(可能是 cv 限定的)类类型,则尝试将其中每个操作数转换为另一个操作数的类型。判断T1类型的操作数表达式E1是否可以转换为匹配T2类型的操作数表达式E2的过程定义如下:
\n\n3.a:如果 E2 是左值:如果 E1 可以隐式转换(第 4 条)到 T2\xe2\x80\x9d 的类型 \xe2\x80\x9creference ,则 E1 可以转换为匹配 E2,但需满足以下约束:在转换中,引用必须直接绑定(8.5.3)到 E1。
\n\n3.b:如果E2是右值,或者上面的转换无法完成:
\n\n3.b.1:如果E1和E2具有类类型,并且基础类类型相同或者一个是另一个的基类:如果T2的类与以下类型相同,则E1可以转换为匹配E2,或者 T1 类的基类,并且 T2 的 cv 资格与 T1 的 cv 资格相同,或者比 T1 的 cv 资格更高。如果应用转换,E1 将更改为 T2 类型的右值,该右值仍引用原始源类对象(或其适当的子对象)。(注:即不进行任何复制。)
\n\n3.b.2:否则(即,如果 E1 或 E2 具有非类类型,或者它们都具有类类型,但底层类不相同或者其中一个类不是另一个的基类):E1 可以转换为如果 E1 可以隐式转换为表达式 E2 在 E2 转换为右值时所具有的类型(或者如果 E2 是右值,则为它所具有的类型),则匹配 E2。
\n\n使用该过程,确定是否可以将第二操作数转换为与第三操作数匹配,以及是否可以将第三操作数转换为与第二操作数匹配。如果两者都可以转换,或者其中之一可以转换但转换不明确,则程序格式错误。如果两者都不能转换,则操作数保持不变,并按如下所述执行进一步检查。如果恰好可以进行一次转换,则该转换将应用于所选操作数,并且在本节的其余部分中使用转换后的操作数代替原始操作数。
如果第二个和第三个操作数是左值并且具有相同的类型,则结果就是该类型并且是左值。
否则,结果是右值。如果第二个和第三个操作数没有相同的类型,并且其中一个具有(可能是 cv 限定的)类类型,则使用重载决策来确定要应用于操作数的转换(如果有)(13.3.1.2、13.6) 。如果重载决策失败,则程序格式错误。否则,应用由此确定的转换,并且在本节的其余部分中使用转换后的操作数代替原始操作数。
对第二个和第三个操作数执行左值到右值 (4.1)、数组到指针 (4.2) 和函数到指针 (4.3) 标准转换。进行这些转换后,应满足以下条件之一:
\n\n6.a:第二个和第三个操作数具有相同的类型;结果就是这种类型。
\n\n6.b:第二和第三操作数具有算术或枚举类型;执行通常的算术转换以使它们成为公共类型,并且结果就是该类型。
\n\n6.c:第二、第三操作数为指针类型,或者一个为指针类型,另一个为空指针常量;执行指针转换(4.10)和限定转换(4.4)以将它们转换为复合指针类型(5.9)。结果是复合指针类型。
\n\n6.d:第二个和第三个操作数具有指向成员类型的指针,或者一个具有指向成员类型的指针,另一个是空指针常量;执行指向成员转换 (4.11) 和限定转换 (4.4) 的指针以将它们转换为公共类型,其 cv 限定应与第二个或第三个操作数的 cv 限定相匹配。结果是普通类型。
| 归档时间: |
|
| 查看次数: |
484 次 |
| 最近记录: |