You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constint i = 0; // decltype(i) is const intboolf(const Widget& w); // decltype(w) is const Widget&// decltype(f) is bool(const Widget&)structPoint {
int x, y; // decltype(Point::x) is int
}; // decltype(Point::y) is int
Widget w; // decltype(w) is Widgetif (f(w)) … // decltype(f(w)) is booltemplate<typename T> // simplified version of std::vectorclassvector {
public:
…
T& operator[](std::size_t index);
…
};
vector<int> v; // decltype(v) is vector<int>
…
if (v[0] == 0) … // decltype(v[0]) is int&
Widget w;
const Widget& cw = w; // auto type deduction : myWidget1's type is Widgetdecltype(auto) myWidget2 = cw; // decltype type deduction : myWidget2's type is const Widget&
注意第一点中强调了entity是一个不被括号包围的标识符。因为当一个标识符被括号包围时,它就是一个左值表达式了,对应上面第二大点的第二小点。比如说int x = 0;,x是一个标识符,所以decltype(x)的结果为int。但是(x)就是一个左值表达式,decltype((x))的结果就是int&。所以下面的用法是不同的:
decltype(auto) f1() {
int x = 0;
…
return x; // decltype(x) is int, so f1 returns int
}
decltype(auto) f2() {
int x = 0;
…
return (x); // decltype((x)) is int&, so f2 returns int&
}
官网的例子能很好的概况decltype最常见的用法:
#include<iostream>structA { double x; };
const A* a;
decltype(a->x) y; // type of y is double (declared type)decltype((a->x)) z = y; // type of z is const double& (lvalue expression)template<typename T, typename U>
autoadd(T t, U u) -> decltype(t + u) // return type depends on template parameters// return type can be deduced since C++14
{
return t + u;
}
intmain()
{
int i = 33;
decltype(i) j = i * 2;
std::cout << "i = " << i << ", "
<< "j = " << j << '\n';
auto f = [](int a, int b) -> int
{
return a * b;
};
decltype(f) g = f; // the type of a lambda function is unique and unnamed
i = f(2, 2);
j = g(3, 3);
std::cout << "i = " << i << ", "
<< "j = " << j << '\n';
}
(完)
朋友们可以关注下我的公众号,获得最及时的更新:
The text was updated successfully, but these errors were encountered:
与模板参数推导和auto推导一样,decltype的结果大多数情况下是正常的,但是也有少部分情况是反直觉的。
decltype介绍
给定一个name或者expression,decltype会告诉你它的类型。
我们先从正常情况开始:
很直观,没有例外情况。 注意:decltype与auto不同,不会消除const和引用。
为什么需要decltype
比如我们需要声明一个函数模板,函数的返回值类型依赖函数参数的类型。在C++11中,常见的例子是返回一个container对应索引的值:
注意:这里的auto跟类型推导没有任何关系,它只是表明了这里使用了C++11的
trailing return type
.decltype(auto)
在C++11中只允许单语句的lambda表达式被推导,在C++14中之中行为被拓展到所有lambda和所有函数,包括多语句。在C++14中,上述代码我们可以简写为:
注意:这里的auto就跟类型推导有关系了。 在前面讲auto推导规则的文章中提到过,auto作用在函数返回值时,使用的是模板参数推导规则,这里就会出现问题:
operator []
我们希望它返回引用,但是使用auto使用模板参数推导规则时,引用会被忽略,所以下面的代码会报错:但是使用
auto -> decltype()
则不会报错,因为这里auto不代表参数参数推导:所以,要想让authAndAccess在使用auto的情况下返回引用,在C++14中,我们可以使用decltype(auto):
decltype(auto)中的auto代表返回值需要被自动推导,decltype代表使用decltype来推导返回值类型。
decltype(auto)不仅可以声明函数返回值,还可以声明变量:
注意(entity)
decltype的规则可以看官网:decltype specifier,概况下可以分为两大类:
decltype ( entity )
: 如果entity是一个不被括号包围的标识符、类访问表达式,那么decltype ( entity )
与entity类型一致。decltype ( expression )
: 如果expression是一个表达式,计算结果为类型T,那么:注意第一点中强调了entity是一个不被括号包围的标识符。因为当一个标识符被括号包围时,它就是一个左值表达式了,对应上面第二大点的第二小点。比如说
int x = 0;
,x是一个标识符,所以decltype(x)
的结果为int。但是(x)就是一个左值表达式,decltype((x))
的结果就是int&。所以下面的用法是不同的:官网的例子能很好的概况decltype最常见的用法:
(完)
朋友们可以关注下我的公众号,获得最及时的更新:
The text was updated successfully, but these errors were encountered: