简体   繁体   English

带花括号的引用类型变量上的 decltype

[英]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 [...] if expr 's type is a reference, ignore the reference part.如果ParamType是非引用 [...] 如果expr的类型是引用,则忽略引用部分。 If [...] expr is const , ingore that too.如果 [...] exprconst ,也忽略它。 If it's volatile , 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){} or T{} ) 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM