Lvalue, Rvalue, Xvalue, Prvalue, Glvalue

Lvalue, Rvalue, Xvalue, Prvalue, Glvalue

c++11中关于什么是lvalue, 什么是rvalue, 什么是xvalue, 什么是prvalue, 什么是…

一直搞得我晕头转向的, 今天下定决心一定要把它搞定, 写了一个程序来判断lvalue, rvalue, prvalue等

 1 namespace test{
 2 
 3 template <typename T>
 4 struct is_lvalue_reference {
 5   const static bool value = false;
 6 };
 7 
 8 template <typename T>
 9 struct is_lvalue_reference<T&> {
10   const static bool value = true;
11 };
12 
13 template <typename T>
14 struct is_rvalue_reference {
15   const static bool value = false;
16 };
17 
18 template <typename T>
19 struct is_rvalue_reference<T&&> {
20   const static bool value = true;
21 };
22 
23 template <typename T>
24 struct is_xvalue {
25   const static bool value = (!is_lvalue_reference<T>::value) && is_rvalue_reference<T>::value;
26 };
27 
28 template <typename T>
29 struct is_prvalue {
30   const static bool value = !(is_lvalue_reference<T>::value || is_rvalue_reference<T>::value);
31 };
32 
33 template <typename T>
34 struct is_lvalue {
35   const static bool value = !(is_xvalue<T>::value || is_prvalue<T>::value);
36 };
37 
38 template <typename T>
39 struct is_rvalue {
40   const static bool value = (is_xvalue<T>::value || is_prvalue<T>::value);
41 };
42 
43 
44 template <typename T>
45 struct is_glvalue{
46   const static bool value = (is_xvalue<T>::value || is_lvalue<T>::value);
47 };
48 
49 }

测试验证:

 1 struct Foo {};
 2 Foo funRetFoo();
 3 Foo& funRetFooLRef();
 4 Foo&& funRetFooRRef();
 5 
 6 
 7 TEST(TypeTraits, isRvalue){
 8 
 9 
10     //base type
11     EXPECT_FALSE(::test::is_lvalue_reference<int>::value);
12     EXPECT_FALSE(::test::is_rvalue_reference<int>::value);
13     EXPECT_FALSE(::test::is_lvalue<int>::value);
14     EXPECT_FALSE(::test::is_xvalue<int>::value);
15     EXPECT_TRUE(::test::is_prvalue<int>::value);
16     EXPECT_FALSE(::test::is_glvalue<int>::value);
17     EXPECT_TRUE(::test::is_rvalue<int>::value);
18 
19     // return obj
20     EXPECT_FALSE(::test::is_lvalue_reference<decltype(funRetFoo())>::value);
21     EXPECT_FALSE(::test::is_rvalue_reference<decltype(funRetFoo())>::value);
22     EXPECT_FALSE(::test::is_lvalue<decltype(funRetFoo())>::value);
23     EXPECT_FALSE(::test::is_xvalue<decltype(funRetFoo())>::value);
24     EXPECT_TRUE(::test::is_prvalue<decltype(funRetFoo())>::value);
25     EXPECT_FALSE(::test::is_glvalue<decltype(funRetFoo())>::value);
26     EXPECT_TRUE(::test::is_rvalue<decltype(funRetFoo())>::value);
27 
28 
29     // return ref obj
30     EXPECT_TRUE(::test::is_lvalue_reference<decltype(funRetFooLRef())>::value);
31     EXPECT_FALSE(::test::is_rvalue_reference<decltype(funRetFooLRef())>::value);
32     EXPECT_TRUE(::test::is_lvalue<decltype(funRetFooLRef())>::value);
33     EXPECT_FALSE(::test::is_xvalue<decltype(funRetFooLRef())>::value);
34     EXPECT_FALSE(::test::is_prvalue<decltype(funRetFooLRef())>::value);
35     EXPECT_TRUE(::test::is_glvalue<decltype(funRetFooLRef())>::value);
36     EXPECT_FALSE(::test::is_rvalue<decltype(funRetFooLRef())>::value);
37 
38     // return rref obj
39     EXPECT_FALSE(::test::is_lvalue_reference<decltype(funRetFooRRef())>::value);
40     EXPECT_TRUE(::test::is_rvalue_reference<decltype(funRetFooRRef())>::value);
41     EXPECT_FALSE(::test::is_lvalue<decltype(funRetFooRRef())>::value);
42     EXPECT_TRUE(::test::is_xvalue<decltype(funRetFooRRef())>::value);
43     EXPECT_FALSE(::test::is_prvalue<decltype(funRetFooRRef())>::value);
44     EXPECT_TRUE(::test::is_glvalue<decltype(funRetFooRRef())>::value);
45     EXPECT_TRUE(::test::is_rvalue<decltype(funRetFooRRef())>::value);
46 
47 
48     int lvalue;
49     // 模拟=号左边
50     EXPECT_TRUE(::test::is_lvalue_reference<decltype(*&lvalue)>::value);
51     EXPECT_FALSE(::test::is_rvalue_reference<decltype(*&lvalue)>::value);
52     EXPECT_TRUE(::test::is_lvalue<decltype(*&lvalue)>::value);
53     EXPECT_FALSE(::test::is_xvalue<decltype(*&lvalue)>::value);
54     EXPECT_FALSE(::test::is_prvalue<decltype(*&lvalue)>::value);
55     EXPECT_TRUE(::test::is_glvalue<decltype(*&lvalue)>::value);
56     EXPECT_FALSE(::test::is_rvalue<decltype(*&lvalue)>::value);
57 
58 
59     //operator++()
60     EXPECT_FALSE(::test::is_lvalue_reference<decltype(lvalue++)>::value);
61     EXPECT_FALSE(::test::is_rvalue_reference<decltype(lvalue++)>::value);
62     EXPECT_FALSE(::test::is_lvalue<decltype(lvalue++)>::value);
63     EXPECT_FALSE(::test::is_xvalue<decltype(lvalue++)>::value);
64     EXPECT_TRUE(::test::is_prvalue<decltype(lvalue++)>::value);
65     EXPECT_FALSE(::test::is_glvalue<decltype(lvalue++)>::value);
66     EXPECT_TRUE(::test::is_rvalue<decltype(lvalue++)>::value);
67 
68     //operator++(int)
69     EXPECT_TRUE(::test::is_lvalue_reference<decltype(++lvalue)>::value);
70     EXPECT_FALSE(::test::is_rvalue_reference<decltype(++lvalue)>::value);
71     EXPECT_TRUE(::test::is_lvalue<decltype(++lvalue)>::value);
72     EXPECT_FALSE(::test::is_xvalue<decltype(++lvalue)>::value);
73     EXPECT_FALSE(::test::is_prvalue<decltype(++lvalue)>::value);
74     EXPECT_TRUE(::test::is_glvalue<decltype(++lvalue)>::value);
75     EXPECT_FALSE(::test::is_rvalue<decltype(++lvalue)>::value);
76 
77 }