c++ decltype关键字的用法

 更新时间:2020年10月20日 10:51:30   作者:半杯茶的小酒杯  
这篇文章主要介绍了c++ decltype关键字的用法,帮助大家更好的理解和学习c++,感兴趣的朋友可以了解下

1. decltype关键字的用途是什么

给定变量的名称或者表达式,decltype返回变量或者表达式的类型。如下所示:

const int i = 0; // decltype(i) is const int

bool f(const Widget& w); // decltype(w) is const Widget&,decltype(f) is bool(const Widget&)

struct Point {

int x, y; // decltype(Point::x) is int, decltype(Point::y) is int

};

Widget w; // decltype(w) is Widget

if (f(w)) ... // decltype(f(w)) is bool

template<typename T>class vector {

public:

...

T& operator[](std::size_t index);...

};

vector<int> v; // decltype(v) is vector<int>

if (v[0] == 0) ... // decltype(v[0]) is int&

2.decltype主要应用场景是模板函数

decltype在实际的开发中主要用于模板函数中,函数的返回值依赖于模板参数类型的情况。如下authAndAccess函数的返回值类型依赖于Container的元素类型。

template<typename Container, typename Index>
auto authAndAccess(Container& c, Index i) -> decltype(c[i]) {

 authenticateUser();

 return c[i];
}

此处的返回值auto并非类型推导的意思,而是C++ 11中的函数返回类型后置的表达方式,表明函数的返回类型在参数列表之后。函数返回类型后置的优势在于我们可以用函数的参数来指定返回值。

在c++ 14中auto关键字可以独立用于对函数的返回值进行类型推导,而不必采用c++ 11中的返回返回类型后置的声明方式:

template<typename Container, typename Index>
auto authAndAccess(Container& c, Index i) {

 authenticateUser();

 return c[i]; // return type deduced from c[i]
}

但上述写法在实际应用针对具体case可能存在问题,比如如果operator[]返回T&,auto的推导机制会返回T,下面的就会编译失败:

std::deque<int> d;

...

authAndAccess(d, 5) = 10; //return d[5], then assign 10 to it; this won't compile!

因为根据auto的推导机制,authAndAccess返回的是右值,所以编译不通过。authAndAccess函数需要声明为如下方式才可以保证该示例编译通过。

template<typename Container, typename Index>
decltype(auto) authAndAccess(Container& c, Index i){

 authenticateUser();

 return c[i];
}

decltype(auto)不仅仅可以用于函数,也可以用于变量,可以完美推导变量的类型。

Widget w;
const Widget& cw = w;
auto myWidget1 = cw; // auto type deduction: myWidget1's type is Widget

decltype(auto) myWidget2 = cw; // decltype type deduction: myWidget2's type is const Widget&

再回到authAndAccess函数

template<typename Container, typename Index>
decltype(auto) authAndAccess(Container& c, Index i);

注意到Container是一个非const的左值引用,这意味着用户可以修改Container内元素的值,同时也意味不能传递右值引用给它。

另外右值容器一般是一个临时对象,会在函数调用结束后不久被销毁,所以当用户传入一个右值引用的时候,一般我们要把返回元素拷贝它的一个副本。如何能够在不重载authAndAccess函数的情况下使它同时支持左值和右值呢?答案是通用引用。

template<typename Container, typename Index>
decltype(auto) authAndAccess(Container&& c,Index i);

为了保证推导结果的正确性,需要在实现中增加完美转发(std::forward)功能。

template<typename Container, typename Index>
decltype(auto)authAndAccess(Container&& c, Index i){

 authenticateUser();

 return std::forward<Container>(c)[i];
} // c++ 14版本
template<typename Container, typename Index>
auto authAndAccess(Container&& c, Index i)
-> decltype(std::forward<Container>(c)[i])
{
 authenticateUser();

 return std::forward<Container>(c)[i];
} // c++ 11版本

3. decltype使用的极端case

decltype(auto) f1() { // decltype(x) is int, so f1 returns int
 int x = 0;
 ...
 return x;
}

decltype(auto) f2() { // decltype((x)) is int&, so f2 returns int&
 int x = 0;
 ...
 return (x);
}

返回了一个局部变量的引用。

4. 需要记住的:

1) decltype总是返回与变量或者表达式完全相同的类型;

2) 对于类型T的非名称的左值表达式,decltype总是返回T&;

以上就是c++ decltype关键字的用法的详细内容,更多关于c++ decltype关键字的资料请关注脚本之家其它相关文章!

相关文章

  • C++ 如何判断四个点是否构成正方形

    C++ 如何判断四个点是否构成正方形

    这篇文章主要介绍了C++ 如何判断四个点是否构成正方形的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • C语言实现C++继承和多态的代码分享

    C语言实现C++继承和多态的代码分享

    本文主要给大家简单讲诉了C和C++的区别以及如何使用C语言模拟实现C++继承和多态,并附上示例代码,是篇相当不错的文章,推荐给喜欢C语言的小伙伴们
    2017-07-07
  • C语言中数组常用的一些排序算法小结

    C语言中数组常用的一些排序算法小结

    数组的排序方法有很多,效率也各不相同,下面这篇文章主要给大家介绍了关于C语言中数组常用的一些排序算法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • C++中临时对象的常见产生情况及其解决的方案

    C++中临时对象的常见产生情况及其解决的方案

    这篇文章主要是探讨常见的临时对象产生的情况,及其如何避免和解决这种临时对象产生的方式。具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Qt6.0 qproperty-*不生效原因解决分析

    Qt6.0 qproperty-*不生效原因解决分析

    这篇文章主要为大家介绍了Qt6.0 qproperty-*不生效原因解决分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • 基于getline()函数的深入理解

    基于getline()函数的深入理解

    本篇文章是对getline()函数的使用进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++中cout的格式使用详细介绍

    C++中cout的格式使用详细介绍

    cout 是C++中 ostream 类型的对象,该类被封装在 < iostream > 库中,该库定义的名字都在命名空间 std 中,所以 cout 全称是 std::cout 。本文重点给大家介绍C++中cout的格式使用,需要的朋友参考下吧
    2021-06-06
  • C++中一维数组与指针的关系详细总结

    C++中一维数组与指针的关系详细总结

    以下是对C++中一维数组与指针的关系进行了详细的总结介绍,需要的朋友可以过来参考下
    2013-09-09
  • C++vector的用法你都知道嘛

    C++vector的用法你都知道嘛

    这篇文章主要为大家详细介绍了C++中vector的用法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • C++常用的#include头文件总结

    C++常用的#include头文件总结

    这篇文章主要介绍了C++常用的#include头文件,对初学者理解C++程序设计大有好处的相关资料
    2014-07-07

最新评论