为什么 `typeid(T&).name()` 的输出为 `T` 而不是 `T&`?
Why is the output of `typeid(T&).name()` given as `T` instead of `T&`?
题主可以查看https://godbolt.org/z/qtjVP6上的相关代码。
为了您的方便,代码贴在下面:
#include<typeinfo>
#include<iostream>
class Widget{};
Widget someWidget;
int main()
{
Widget&& var1 = Widget{}; // here, “&&” means rvalue reference
auto&& var2 = var1; // here, “&&” does not mean rvalue reference
std::cout << typeid(var2).name() << std::endl;
}
输出:6Widget
echo 6Widget | c++filt -t
表示 Widget
。
如果能在这个问题上提供一些帮助,我将不胜感激。
根据 C++ Reference(强调我的):
1) Refers to a std::type_info
object representing the type type. If type is a reference type, the result refers to a std::type_info
object representing the referenced type.
因此对于 type = T&
,typeid(type)
将给出大约 T
的结果(引用已删除)。
IMO 很容易理解,就所有目的而言,T&
类型的变量在功能上等同于 T
.
类型之一
尽管 iBug 给出的 在某种程度上是正确的,但它并不真正适用于您的情况。
让我们看看 C++ 标准对此有何规定。我们可以看到 [expr]p5 说:
5 If an expression initially has the type “reference to T” ([dcl.ref], [dcl.init.ref]), the type is adjusted to T prior to any further analysis. The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression.
这就是说在:
std::cout << typeid(var2).name() << std::endl;
在进一步计算表达式之前,var2
的类型从 Widget&
调整为 Widget
。
现在更容易理解为什么 typeid(var2).name()
returns 对应类型 Widget
.
的字符串
如果您想更深入地挖掘,[expr.typeid]p3 说:
3 When typeid is applied to an expression other than a glvalue of a polymorphic class type, the result refers
to a std::type_info object representing the static type of the expression. Lvalue-to-rvalue (4.1), array-topointer
(4.2), and function-to-pointer (4.3) conversions are not applied to the expression. If the type of the
expression is a class type, the class shall be completely-defined. The expression is an unevaluated operand
(Clause 5).
这基本上意味着 typeid(var2)
中的 var2
是一个非多态 class 类型的 glvalue 并且用于表达式这样一个类型,该类型就是它的静态类型。因此类型是 Widget
.
有关详细信息,请参阅 。
题主可以查看https://godbolt.org/z/qtjVP6上的相关代码。
为了您的方便,代码贴在下面:
#include<typeinfo>
#include<iostream>
class Widget{};
Widget someWidget;
int main()
{
Widget&& var1 = Widget{}; // here, “&&” means rvalue reference
auto&& var2 = var1; // here, “&&” does not mean rvalue reference
std::cout << typeid(var2).name() << std::endl;
}
输出:6Widget
echo 6Widget | c++filt -t
表示 Widget
。
如果能在这个问题上提供一些帮助,我将不胜感激。
根据 C++ Reference(强调我的):
1) Refers to a
std::type_info
object representing the type type. If type is a reference type, the result refers to astd::type_info
object representing the referenced type.
因此对于 type = T&
,typeid(type)
将给出大约 T
的结果(引用已删除)。
IMO 很容易理解,就所有目的而言,T&
类型的变量在功能上等同于 T
.
尽管 iBug 给出的
让我们看看 C++ 标准对此有何规定。我们可以看到 [expr]p5 说:
5 If an expression initially has the type “reference to T” ([dcl.ref], [dcl.init.ref]), the type is adjusted to T prior to any further analysis. The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression.
这就是说在:
std::cout << typeid(var2).name() << std::endl;
在进一步计算表达式之前,var2
的类型从 Widget&
调整为 Widget
。
现在更容易理解为什么 typeid(var2).name()
returns 对应类型 Widget
.
如果您想更深入地挖掘,[expr.typeid]p3 说:
3 When typeid is applied to an expression other than a glvalue of a polymorphic class type, the result refers to a std::type_info object representing the static type of the expression. Lvalue-to-rvalue (4.1), array-topointer (4.2), and function-to-pointer (4.3) conversions are not applied to the expression. If the type of the expression is a class type, the class shall be completely-defined. The expression is an unevaluated operand (Clause 5).
这基本上意味着 typeid(var2)
中的 var2
是一个非多态 class 类型的 glvalue 并且用于表达式这样一个类型,该类型就是它的静态类型。因此类型是 Widget
.
有关详细信息,请参阅