工具确定表达式的值类别:了解使用引用时的结果

问题描述 投票:0回答:1

查看值类别的定义,我尝试了此处提出的代码片段:https://stackoverflow.com/a/16638081/21691539

template <typename T>
struct value_category {
    // Or can be an integral or enum value
    static constexpr auto value = "prvalue";
};

template <typename T>
struct value_category<T&> {
    static constexpr auto value = "lvalue";
};

template <typename T>
struct value_category<T&&> {
    static constexpr auto value = "xvalue";
};

// Double parens for ensuring we inspect an expression,
// not an entity
#define VALUE_CATEGORY(expr) value_category<decltype((expr))>::value

但是测试它时我不明白它在暗示引用的情况下的输出。这是我的“测试台”:

#include <iostream>

struct S {
    int val;
    int& rval = val;
};

int f();
int& rf();

// VALUE_CATEGORY as in previous snippet

#define SHOW_CATEGORY(expr) std::cout << #expr << "\t" << VALUE_CATEGORY(expr) << '\n';

int main() {
    SHOW_CATEGORY(f());
    SHOW_CATEGORY(rf());    // expecting prvalue, got lvalue
    SHOW_CATEGORY(S{}.val);
    SHOW_CATEGORY(S{}.rval);    // expecting xvalue, got lvalue
}

直播

和输出

f()      prvalue
rf()     lvalue
S{}.val  xvalue
S{}.rval lvalue

在表达式与引用相关的两种情况下,我都会得到意想不到的

lvalue

该片段正确吗?在这种情况下为什么?这是错误的吗,那么正确的价值类别是什么(以及为什么)?


注意来自 https://timsong-cpp.github.io/cppwp/n4861/basic.lval#4.4 我知道

S{}.rval
不是
xvalue
,尽管我想知道其合理性。

c++ language-lawyer decltype value-categories
1个回答
0
投票

该片段正确吗?在本例中为什么?

是的,如下所述。

第一个

S{}.rval
是一个左值表达式,根据 basic.ref 指出:

如果

E2
被声明为“对 T 的引用”类型,则 E1.E2 是
T
类型的左值。

在您的示例中,

rval
int&
,这意味着
S{}.rval
是左值表达式。


接下来调用

rf()
也是一个左值表达式。来自 expr.call:

如果结果类型是左值引用类型或对函数类型的右值引用,则函数调用是左值;如果结果类型是对对象类型的右值引用,则函数调用是 xvalue;否则是纯右值。

© www.soinside.com 2019 - 2024. All rights reserved.