刚刚看到一篇 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. [ABC262B] Triangle (Easier)

    Problem Statement You are given a simple undirected graph with $N$ vertices and $M$ edges. The verti ...

  2. StarBlog - 2023年底更新内容一览

    前言 先说一下我对 StarBlog 这个系列的文章的规划吧,在 StarBlog 的 1.x 版本,我会同步更新两个系列的文章 博客前台+接口开发笔记 (即当前已发布的这一系列文章) 博客Vue后台 ...

  3. 从Redis读取.NET Core配置

    在本文中,我们将创建一个自定义的.NET Core应用配置源和提供程序,用于从Redis中读取配置.在此之前,您需要稍微了解一些.NET Core配置提供程序的工作原理,相关的内容可以在Microso ...

  4. Freezable ---探索WPF中Freezable承载数据的原理

    引言 在之前写的一篇文章[WPF --- 如何以Binding方式隐藏DataGrid列]中,我先探索了 DataGridTextColumn 为什么不在可视化树结构内?又给出了解决方案,使用 Fre ...

  5. javacv实现屏幕录制(一)

    javacv实现屏幕录制(一) javacv从入门到入土系列,发现了个好玩的东西,视频处理,于是我想搞个屏幕录屏,我百度了一下,copy那些代码我没有实现过,那些代码也没有说明,只好去官网看文档找资料 ...

  6. JavaImprove--Lesson05--Arrays,对象排序,Lambda表达式,方法引用简化Lambda表达式

    一.Arrays 用来操作数组的一个工具类 在Java中,没有内置的"Arrays工具类",但有一个名为java.util.Arrays的类,它包含了一些用于操作数组的静态方法.这 ...

  7. 文心一言 VS chatgpt (17)-- 算法导论4.1 3~4题

    三.在你的计算机上实现最大子数组问题的暴力算法和递归算法.请指出多大的问题规模n0是性能交叉点一一从此之后递归算法将击败暴力算法?然后,修改递归算法的基本情况一一当问题规模小于 n0 时采用暴力算法. ...

  8. GaussDB(for MySQL)如何在存储架构设计上做到高可靠、高可用

    摘要: GaussDB(for MySQL)通过ND算子下推解决存储节点和计算节点之间的传输速度,减少网络开销这个难题. 数据库作为高效稳定处理海量数据交易/分析的坚强数据底座,底层架构设计的重要性不 ...

  9. ModelArts黑科技揭秘|弹性训练,让训练资源张弛有度

    摘要:AI进入产业的门槛变高,开发者想要做出优秀的AI模型就不得不在算力和成本之间折中,怎么办? 为帮助企业在AI落地过程中进一步实现降本增效,华为云推出AI黑科技--弹性训练. 今年,AI界最被热议 ...

  10. 如何快速上手 angular.js

    摘要:angular.js 准确的来说,应该不是一个框架,是一个 js 库,一个依赖于 jQuery 的进一步封装,去除繁琐的 DOM 操作,使用数据驱动的 MVC 模块化库. 哎,很难受,连续两个大 ...