[英]decltype on the variable of reference type with curly braces
Consider the following code :考虑以下代码:
#include <type_traits>
int main() {
const int& p = 42;
auto v1 = decltype(p){};
static_assert(std::is_same_v<decltype(v1), int>);
decltype(p) v2{};
static_assert(std::is_same_v<decltype(v2), const int&>);
// auto v3 = X(const int&)X {};
}
Type of v1
is deduced as int
. v1
的类型推断为int
。 At the same time type of v2
is expectedly deduced as const int&
.同时,预计
v2
的类型被推断为const int&
。 I think the first step for v1
could be treated as adding one more type alias using T = decltype(p);
我认为
v1
的第一步可以被视为using T = decltype(p);
添加一个类型别名。 and then auto v4 = T{};
然后
auto v4 = T{};
. . How this expression (
decltype(p){}
or T{}
) is treated by compiler?编译器如何处理这个表达式(
decltype(p){}
或T{}
)? I know that {}
part is for instantiation, but how the resulting type of v1
is not a reference type?我知道
{}
部分用于实例化,但是v1
的结果类型如何不是引用类型?
Yet another question: is there a way to declare v3
variable of the same type as v1
using explicitly noted type const int&
(instead of decltype(p)
)?还有一个问题:有没有办法使用明确指出的类型
const int&
(而不是decltype(p)
)声明与v1
相同类型的v3
变量?
Any links to standard would be appreciated.任何与标准的链接将不胜感激。
(To the downvoter(s): if you downvoted because you think quoting Scott Meyers is not equivalent to quoting the standard, oh well...) (致downvoter(s):如果你因为你认为引用Scott Meyers 不等于引用标准而投反对票,那么好吧......)
As you can read from Effective Modern C++ (augmented with the part of the errata that you can reach by searching for Case 2:
at that link, and that just makes the following read simpler, but it's not essential to the question):正如您可以从Effective Modern C++中看到的那样(通过在该链接上搜索
Case 2:
可以达到的勘误表部分进行了扩充,这只会使以下阅读变得更简单,但这对问题来说并不重要):
If
ParamType
is a non-reference [...] ifexpr
's type is a reference, ignore the reference part.如果
ParamType
是非引用 [...] 如果expr
的类型是引用,则忽略引用部分。 If [...]expr
isconst
, ingore that too.如果 [...]
expr
是const
,也忽略它。 If it'svolatile
, also ignore that.如果它是
volatile
,也请忽略它。
where param
is the declaration specifier, which in your case is just auto
, ie a non-reference.其中
param
是声明说明符,在您的情况下只是auto
,即非引用。
In other words, you're creating v1
via plain auto
(not auto&
), ie by copy, so it does not matter whether you are initializing it with an entity which is reference or not, or even with const
or not (or volatile
or not, fwiw), because you're copying it.换句话说,您是通过普通
auto
(不是auto&
)创建v1
,即通过复制,因此无论您是否使用引用实体初始化它,甚至是否使用const
(或volatile
或不,fwiw),因为您正在复制它。
Think about the simpler case,想想更简单的情况,
int i = 3;
int& p = i;
auto v1 = p;
as far as v1
is concerned, it's really not important whether it is initalized with one ( i
) or the other ( p
) name by which the same entity is known, because it will get a copy of whatever value that entity has.就
v1
而言,它是用一个 ( i
) 名称还是另一个 ( p
) 名称初始化并不重要,因为它会获得该实体具有的任何值的副本。
auto
type deduction works just like template type deduction (except for a difference in how they deal with braced initializer, which is not relevant in this case), and for both of them you can refer to Scott Meyers' Effective Modern C++ . auto
类型推导就像模板类型推导一样工作(除了它们处理大括号初始化程序的方式不同,这在本例中不相关),对于它们两者,您可以参考 Scott Meyers 的Effective Modern C++ 。
auto v4 = T{}
;.auto v4 = T{}
;. How this expression (decltype(p){}
orT{}
) is treated by compiler?编译器如何处理这个表达式(
decltype(p){}
或T{}
)? I know that{}
part is for instantiation, but how the result type is not a reference type?我知道
{}
部分用于实例化,但结果类型如何不是引用类型?
The result decltype(p){}
is a reference type.结果
decltype(p){}
是一个引用类型。 It's the usage of auto
that drops the const
and reference qualifiers.是
auto
的使用删除了const
和 reference 限定符。 The deduction of the type is explained here , and they're the same as those used for template type deduction.这里解释了类型的推导,它们与模板类型推导使用的相同。 You could use
decltype(auto)
instead to keep those qualifiers (or, in this particular case, you could use const auto&
).您可以改用
decltype(auto)
来保留这些限定符(或者,在这种特殊情况下,您可以使用const auto&
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.