Lvalue, Rvalue, Xvalue, Prvalue, Glvalue
c++11中关于什么是lvalue, 什么是rvalue, 什么是xvalue, 什么是prvalue, 什么是…
一直搞得我晕头转向的, 今天下定决心一定要把它搞定, 写了一个程序来判断lvalue, rvalue, prvalue等
namespace test{
template <typename T>
struct is_lvalue_reference {
const static bool value = false;
};
template <typename T>
struct is_lvalue_reference<T&> {
const static bool value = true;
};
template <typename T>
struct is_rvalue_reference {
const static bool value = false;
};
template <typename T>
struct is_rvalue_reference<T&&> {
const static bool value = true;
};
template <typename T>
struct is_xvalue {
const static bool value = (!is_lvalue_reference<T>::value) && is_rvalue_reference<T>::value;
};
template <typename T>
struct is_prvalue {
const static bool value = !(is_lvalue_reference<T>::value || is_rvalue_reference<T>::value);
};
template <typename T>
struct is_lvalue {
const static bool value = !(is_xvalue<T>::value || is_prvalue<T>::value);
};
template <typename T>
struct is_rvalue {
const static bool value = (is_xvalue<T>::value || is_prvalue<T>::value);
};
template <typename T>
struct is_glvalue{
const static bool value = (is_xvalue<T>::value || is_lvalue<T>::value);
};
}
测试验证:
struct Foo {};
Foo funRetFoo();
Foo& funRetFooLRef();
Foo&& funRetFooRRef();
TEST(TypeTraits, isRvalue){
//base type
EXPECT_FALSE(::test::is_lvalue_reference<int>::value);
EXPECT_FALSE(::test::is_rvalue_reference<int>::value);
EXPECT_FALSE(::test::is_lvalue<int>::value);
EXPECT_FALSE(::test::is_xvalue<int>::value);
EXPECT_TRUE(::test::is_prvalue<int>::value);
EXPECT_FALSE(::test::is_glvalue<int>::value);
EXPECT_TRUE(::test::is_rvalue<int>::value);
// return obj
EXPECT_FALSE(::test::is_lvalue_reference<decltype(funRetFoo())>::value);
EXPECT_FALSE(::test::is_rvalue_reference<decltype(funRetFoo())>::value);
EXPECT_FALSE(::test::is_lvalue<decltype(funRetFoo())>::value);
EXPECT_FALSE(::test::is_xvalue<decltype(funRetFoo())>::value);
EXPECT_TRUE(::test::is_prvalue<decltype(funRetFoo())>::value);
EXPECT_FALSE(::test::is_glvalue<decltype(funRetFoo())>::value);
EXPECT_TRUE(::test::is_rvalue<decltype(funRetFoo())>::value);
// return ref obj
EXPECT_TRUE(::test::is_lvalue_reference<decltype(funRetFooLRef())>::value);
EXPECT_FALSE(::test::is_rvalue_reference<decltype(funRetFooLRef())>::value);
EXPECT_TRUE(::test::is_lvalue<decltype(funRetFooLRef())>::value);
EXPECT_FALSE(::test::is_xvalue<decltype(funRetFooLRef())>::value);
EXPECT_FALSE(::test::is_prvalue<decltype(funRetFooLRef())>::value);
EXPECT_TRUE(::test::is_glvalue<decltype(funRetFooLRef())>::value);
EXPECT_FALSE(::test::is_rvalue<decltype(funRetFooLRef())>::value);
// return rref obj
EXPECT_FALSE(::test::is_lvalue_reference<decltype(funRetFooRRef())>::value);
EXPECT_TRUE(::test::is_rvalue_reference<decltype(funRetFooRRef())>::value);
EXPECT_FALSE(::test::is_lvalue<decltype(funRetFooRRef())>::value);
EXPECT_TRUE(::test::is_xvalue<decltype(funRetFooRRef())>::value);
EXPECT_FALSE(::test::is_prvalue<decltype(funRetFooRRef())>::value);
EXPECT_TRUE(::test::is_glvalue<decltype(funRetFooRRef())>::value);
EXPECT_TRUE(::test::is_rvalue<decltype(funRetFooRRef())>::value);
int lvalue;
// 模拟=号左边
EXPECT_TRUE(::test::is_lvalue_reference<decltype(*&lvalue)>::value);
EXPECT_FALSE(::test::is_rvalue_reference<decltype(*&lvalue)>::value);
EXPECT_TRUE(::test::is_lvalue<decltype(*&lvalue)>::value);
EXPECT_FALSE(::test::is_xvalue<decltype(*&lvalue)>::value);
EXPECT_FALSE(::test::is_prvalue<decltype(*&lvalue)>::value);
EXPECT_TRUE(::test::is_glvalue<decltype(*&lvalue)>::value);
EXPECT_FALSE(::test::is_rvalue<decltype(*&lvalue)>::value);
//operator++()
EXPECT_FALSE(::test::is_lvalue_reference<decltype(lvalue++)>::value);
EXPECT_FALSE(::test::is_rvalue_reference<decltype(lvalue++)>::value);
EXPECT_FALSE(::test::is_lvalue<decltype(lvalue++)>::value);
EXPECT_FALSE(::test::is_xvalue<decltype(lvalue++)>::value);
EXPECT_TRUE(::test::is_prvalue<decltype(lvalue++)>::value);
EXPECT_FALSE(::test::is_glvalue<decltype(lvalue++)>::value);
EXPECT_TRUE(::test::is_rvalue<decltype(lvalue++)>::value);
//operator++(int)
EXPECT_TRUE(::test::is_lvalue_reference<decltype(++lvalue)>::value);
EXPECT_FALSE(::test::is_rvalue_reference<decltype(++lvalue)>::value);
EXPECT_TRUE(::test::is_lvalue<decltype(++lvalue)>::value);
EXPECT_FALSE(::test::is_xvalue<decltype(++lvalue)>::value);
EXPECT_FALSE(::test::is_prvalue<decltype(++lvalue)>::value);
EXPECT_TRUE(::test::is_glvalue<decltype(++lvalue)>::value);
EXPECT_FALSE(::test::is_rvalue<decltype(++lvalue)>::value);
}
Lvalue, Rvalue, Xvalue, Prvalue, Glvalue的更多相关文章
- C++ lvalue,prvalue,xvalue,glvalue和rvalue详解(from cppreference)
General 每一个C++表达式(一个操作符和它的操作数,一个字面值,一个变量名等等)都代表着两个独立属性:类型+属性分类.在现代C++中 glvalue(泛左值) = lvalue (传统意义上的 ...
- lvalue & rvalue
https://www.youtube.com/watch?v=UTUdhjzws5g 作者:知乎用户链接:https://www.zhihu.com/question/50652989/answer ...
- C++98/11/17表达式类别
目标 以下代码能否编译通过,能否按照期望运行?(点击展开) #include <utility> #include <type_traits> namespace cpp98 ...
- 理解lvalue和rvalue
今天看C++模板的资料,里面说到lvalue,rvalue的问题,这个问题以前也看到过,也查过相关资料,但是没有考虑得很深,只知道rvalue不能取地址,不能赋值等等一些规则.今天则突然有了更深层次的 ...
- Value Categories
Value categories Three primary categories primary categories mixed special Each C++ expression (an o ...
- C++11的value category(值类别)以及move semantics(移动语义)
转载请保留以下声明 作者:赵宗晟 出处:http://www.cnblogs.com/zhao-zongsheng/p/value_categories_and_move_semantics.html ...
- C++ 新特性 笔记
摘录 constexptr C++14尝鲜:constexpr函数(编译期函数) 总结来说,就是在c++11之前,要实现编译期数值计算需要繁琐的模板元编程.在c++11 中,可以是函数,在一句rutu ...
- C++11引用临时变量的终极解析
工作中遇到一个引用临时变量的问题,经过两天的学习,私以为:不仅弄明白了这个问题,还有些自己的独到见解. 这里使用一个简单的例子来把自己的学习过程和理解献给大家,如果有什么问题请不吝指正. **** ...
- 对C++11中的`移动语义`与`右值引用`的介绍与讨论
本文主要介绍了C++11中的移动语义与右值引用, 并且对其中的一些坑做了深入的讨论. 在正式介绍这部分内容之前, 我们先介绍一下rule of three/five原则, 与copy-and-swap ...
随机推荐
- VS2013中修改.dll工程项目的.lib和.dll的输出路径
一个dll工程,生成的两个东西是我们需要的:.lib和.dll,在实际开发过程中我们往往希望这两个东西直接输出到特定文件夹,对于这两个的修改: 设置好之后,对于调用该dll的exe工程,将exe的输出 ...
- mysql 经典题目
题目1:实现如下效果 CREATE TABLE IF NOT EXISTS tb_amount( `Id` INT NOT NULL AUTO_INCREMENT, `), `), `Amount` ...
- RPC进阶篇
RPC实现结构拆解 RPC过程调用详解:RPC 服务端通过 RpcServer 去导出(export)远程接口方法,而客户端通过 RpcClient 去引入(import)远程接口方法. 客户端像调用 ...
- 轻松学习Linux系统安装篇之fdisk命令行工具的使用
fdisk 的介绍: fdisk 命令是磁盘分区表操作工具:和以前Dos和windows下的分区工具功能一样:fdsik 能划分磁盘成为若干个区,同时也能为每个分区指定分区的文件系统 ...
- 基于Storm 分布式BP神经网络,将神经网络做成实时分布式架构
将神经网络做成实时分布式架构: Storm 分布式BP神经网络: http://bbs.csdn.net/topics/390717623 流式大数据处理的三种框架:Storm,Spark和Sa ...
- 第三百三十五天 how can I 坚持
晚上回来看了个奥斯卡影片,<疯狂的麦克斯-狂暴之路>,挺震撼的场面.导演确实挺厉害,不知道是怎么想象出来的. 睡觉,明天继续.
- Axis2与Web项目整合
一.说明: 上一篇介绍了通过使用Axis2来发布和调用WebService,但是是把WebService发布在Axis2提供的项目中,如果我们需要在自己的Web项目中来使用Axis2发布WebServ ...
- 思科ASA系列防火墙配置手册
使用console连接线登录方法 1.使用cisco的console连接线,连接设备的console口和计算机com口(笔记本用USB转COM口连接线)2.使用超级终端或secureCRT软件连接设备 ...
- jquery的clone方法bug的修复
最近发现jquery的clone的bug,textarea和select的jquery的clone方法有问题,textarea和select的值clone的时候会丢掉,在网上发现一个插件,下载地址如下 ...
- 在VSTO界面中,调用xll中的函数
最近研究各种有点迷茫了,原来Xll的加载宏直接可以在C#中调用的,我又各种Out了. 先说明一下,在VBA中,如何调用吧 XLLFound = Application.RegisterXLL(This ...