刚刚看到一篇 C++ 博客,里面讲到用模板偏特化和 decltype() 识别值类别:lvalue glvalue xvalue rvalue prvalue。依照博客的方法试了一下,发现根本行不通。之后,我查阅了一下 cppreference.com 关于 decltype 关键字的描述,发现了 decltype((表达式)) 具有以下特性:

  • 如果 表达式 的值类别是 xvaluedecltype 将会产生 T&&
  • 如果 表达式 的值类别是 lvaluedecltype 将会产生 T&
  • 如果 表达式 的值类别是 prvaluedecltype 将会产生 T

也就是可以细分 xvaluelvalue,于是尝试将模板偏特化和 decltype(()) 结合,发现这种方法可行。

#include <iostream>
#include <type_traits> template<typename T> struct is_lvalue : std::false_type {};
template<typename T> struct is_lvalue<T&> : std::true_type {}; template<typename T> struct is_xvalue : std::false_type {};
template<typename T> struct is_xvalue<T&&> : std::true_type {}; template<typename T> struct is_glvalue : std::integral_constant<bool, is_lvalue<T>::value || is_xvalue<T>::value> {};
template<typename T> struct is_prvalue : std::integral_constant<bool, !is_glvalue<T>::value> {};
template<typename T> struct is_rvalue : std::integral_constant<bool, !is_lvalue<T>::value> {}; struct A
{
int x = 1;
}; int main()
{
A a; std::cout << std::boolalpha
<< is_lvalue<decltype(("abcd"))>::value << std::endl
<< is_glvalue<decltype(("abcd"))>::value << std::endl
<< is_xvalue<decltype(("abcd"))>::value << std::endl
<< is_rvalue<decltype(("abcd"))>::value << std::endl
<< is_prvalue<decltype(("abcd"))>::value << std::endl
<< std::endl
<< is_lvalue<decltype((a))>::value << std::endl
<< is_glvalue<decltype((a))>::value << std::endl
<< is_xvalue<decltype((a))>::value << std::endl
<< is_rvalue<decltype((a))>::value << std::endl
<< is_prvalue<decltype((a))>::value << std::endl
<< std::endl
<< is_lvalue<decltype((A()))>::value << std::endl
<< is_glvalue<decltype((A()))>::value << std::endl
<< is_xvalue<decltype((A()))>::value << std::endl
<< is_rvalue<decltype((A()))>::value << std::endl
<< is_prvalue<decltype((A()))>::value << std::endl
<< std::endl
<< is_lvalue<decltype((A().x))>::value << std::endl
<< is_glvalue<decltype((A().x))>::value << std::endl
<< is_xvalue<decltype((A().x))>::value << std::endl
<< is_rvalue<decltype((A().x))>::value << std::endl
<< is_prvalue<decltype((A().x))>::value << std::endl
;
}

输出

true
true
false
false
false true
true
false
false
false false
false
false
true
true false
true
true
true
false

所有的输出结果都符合预期。

C++ 利用模板偏特化和 decltype(()) 识别表达式的值类别的更多相关文章

  1. [转]Traits 编程技法+模板偏特化+template参数推导+内嵌型别编程技巧

    STL中,traits编程技法得到了很大的应用,了解这个,才能一窥STL奥妙所在. 先将自己所理解的记录如下: Traits技术可以用来获得一个 类型 的相关信息的. 首先假如有以下一个泛型的迭代器类 ...

  2. C++ 函数模板“偏特化”

         模板是C++中很重要的一个特性,利用模板可以编写出类型无关的通用代码,极大的减少了代码量,提升工作效率.C++中包含类模板.函数模板,对于需要特殊处理的类型,可以通过特化的方式来实现特定类型 ...

  3. 函数模板“偏特化” (C++)

         模板是C++中很重要的一个特性,利用模板可以编写出类型无关的通用代码,极大的减少了代码量,提升工作效率.C++中包含类模板.函数模板,对于需要特殊处理的类型,可以通过特化的方式来实现特定类型 ...

  4. 【转】traits技术及模板偏特化

    #include <iostream> using namespace std; struct __xtrue_type { }; // define two mark-type stru ...

  5. C++中模板的特化与偏特化

    1.引言 C++中的模板分为类模板和函数模板,虽然它引进到C++标准中的时间不是很长,但是却得到了广泛的应用,这一点在STL中有着充分的体现.目前,STL在C++社区中得到了广泛的关注.应用和研究.理 ...

  6. [转]C++中模板的特化与偏特化

    转载自:http://hi.baidu.com/klcdyx2008/blog/item/5adbf77b79f316f90bd1873c.html 1.引言C++中的模板分为类模板和函数模板,虽然它 ...

  7. 【校招面试 之 C/C++】第2题 函数模板、类模板、特化、偏特化

    1.C++模板 说到C++模板特化与偏特化,就不得不简要的先说说C++中的模板.我们都知道,强类型的程序设计迫使我们为逻辑结构相同而具体数据类型不同的对象编写模式一致的代码,而无法抽取其中的共性,这样 ...

  8. oop &&GP 模板 ---> 特化和偏特化

    OOP面向对象编程 GP泛型编程(generic programming) 两者的主要区别就是OOP将数据和对数据的操作放在一起, GP就是将数据和操作独立开来 GP:   数据就是container ...

  9. C++模板的特化与偏特化

    http://cppblog.com/SmartPtr/archive/2007/07/04/27496.html (1) 类模板定义一个栈的类模板,它可以用来容纳不同的数据类型 template & ...

  10. C++模板特化与偏特化

    C++模板 说到C++模板特化与偏特化,就不得不简要的先说说C++中的模板.我们都知道,强类型的程序设计迫使我们为逻辑结构相同而具体数据类型不同的对象编写模式一致的代码,而无法抽取其中的共性,这样显然 ...

随机推荐

  1. Selenium接管已经打开的浏览器并爬取数据

    """ P.S:需要接管现有浏览器 ** 使用步骤: 1.打开浏览器,设置好远程调试端口,并扫描登录淘宝. chrome.exe --remote-debugging-p ...

  2. Spring源码学习之Web数据绑定器WebDataBinder

    WebDataBinder 1.描述 特殊的数据绑定器用于从web请求参数到JavaBean对象的数据绑定.专为web环境,但不依赖于Servlet API;作为更具体的DataBinder变体的基类 ...

  3. 谷粒学院通用工具类R类

    import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.HashMap; import ...

  4. 新报: 根据IP获取物理地址不需要调用接口啦

    一. 复制data文件夹到自己的项目当中 可以进行加载到这个文件即可 博主放入在项目的根目录当中 请移步Gitee pull 该文件 https://gitee.com/yangbuyi/ip_fil ...

  5. Golang标准库 container/list(双向链表) 的图文解说

    Golang标准库 container/list(双向链表) 的图文解说 提到单向链表,大家应该是比较熟悉的了.今天介绍的是 golang 官方库提供的 双向链表. 1.基础介绍 单向链表中的每个节点 ...

  6. 网安区过年-Log4j2

    Log4j2-2021 漏洞原理 Apache Log4j 2 是Java语言的日志处理套件,使用极为广泛.在其2.0到2.14.1版本中存在一处JNDI注入漏洞,攻击者在可以控制日志内容的情况下,通 ...

  7. gsamplerCubeArrayShadow isn't supported in textureGrad, textureLod or texture with bias

    问题描述 跑rust的Bevy示例程序 运行3d的示例,cargo run --example 3d_shapes 发现报错: INFO bevy_render::renderer: AdapterI ...

  8. dfs之迭代加深

    为什么要用迭代加深 \(dfs\) 每次会选择搜索树的一个分支,不断深入,直到达到递归边界条件:但这种搜索策略带有一定的缺陷性: 如果搜索树的某一个分支中的节点个数特别多,但是答案并不在这棵子树里面, ...

  9. 5分钟搞定vue3函数式弹窗

    前言 最近接到一个需求,需要在一些敏感操作进行前要求输入账号和密码,然后将输入的账号和密码加到接口请求的header里面.如果每个页面都去手动导入弹窗组件,在点击按钮后弹出弹窗.再拿到弹窗返回的账号密 ...

  10. 谈谈muduo库的销毁连接对象——C++程序内存管理和线程安全的极致体现

    前言 网络编程的连接断开一向比连接建立复杂的多,这一点在陈硕写的muduo库中体现的淋漓尽致,同时也充分体现了C++程序在对象生命周期管理上的复杂性,稍有不慎,满盘皆输. 为了纪念自己啃下muduo库 ...