首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函数返回lvalue,始终返回lvalue引用。

函数返回lvalue,始终返回lvalue引用。
EN

Stack Overflow用户
提问于 2020-11-16 17:03:05
回答 3查看 335关注 0票数 7

有效c++第3项中的Scott说

将解密类型应用于名称的

生成该名称的声明类型。名称通常是lvalue表达式,但不影响解密类型的行为。然而,对于比名称更复杂的lvalue表达式,解密类型通常确保报告的类型是lvalue引用。也就是说,如果名称以外的lvalue表达式的类型为T,则解密类型报告为T&。这很少有任何影响,因为大多数lvalue表达式的类型本质上包括一个lvalue引用限定符。例如,返回lvalue的函数总是返回lvalue引用。

当他说函数返回lvalue时,意味着什么?例如,总是返回lvalue引用。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-11-16 17:14:35

它说的都是真的!

没有办法创建一个函数,因此它的返回类型不是T&,但是调用它会产生一个lvalue表达式。

每个其他的返回类型都会导致函数调用是一个rvalue表达式。

当您考虑到通过引用“返回”已经存在的东西的唯一方法时,这是很直观的--否则函数调用的结果总是“临时的”,不管是因为它在复制某个局部变量,还是因为它正在从某个局部变量中移动。

这个规则的可能例外,返回T&&,也不适用,因为它们产生rvalue表达式(这是移动语义工作的原因,因为只有rvalue表达式可以绑定到T&&参数)。

Scott报告了语言规则的一个结果,并告诉我们,同样的结果被用作decltype规则之一的理由。

可以说,他本可以这样说得更清楚:

是调用lvalue的唯一函数,是返回lvalue引用的函数。

票数 3
EN

Stack Overflow用户

发布于 2020-11-16 17:25:19

首先,我们不难想出一个lvalue表达式的例子,它也是一个名称:

代码语言:javascript
复制
int x{42};
x;  // 'x' here is a name and an lvalue expression

但是,什么不是名字呢?

例如,考虑

代码语言:javascript
复制
int f() {}

这里调用的f()不是lvalue表达式。实际上,没有太多的东西不是名称,而是lvalue表达式,Scott只是对所有实际上是lvalue表达式而不是名称的事物表示,decltype报告的对应类型是lvalue引用类型。

代码语言:javascript
复制
#include <type_traits>

int f() { return 42; };
int& g() { static int g_x; return g_x; }

int main() {
    int x;
    int arr[3] = {1, 2, 3};

    static_assert(
        std::is_same_v<decltype(x), int>, "");
    //                          ^ - 'x' is a name, and an lvalue

    static_assert(
        std::is_same_v<decltype(arr[1]), int&>, "");
    //                          ^^^^^^ - 'arr[1]' is an lvalue expression
    
    static_assert(
        std::is_same_v<decltype((x)), int&>, "");
    //                          ^^^ - '(x)' is an lvalue expression
    
        static_assert(
        std::is_same_v<decltype(f()), int>, "");
    //                          ^^^ - 'f()' is not an lvalue
    
            static_assert(
        std::is_same_v<decltype(g()), int&>, "");
    //                          ^^^ - 'g()' returns an lvalue
}
票数 0
EN

Stack Overflow用户

发布于 2020-11-16 17:27:07

给予:

代码语言:javascript
复制
template<typename T> struct foo;
foo<decltype(*(int*)0)> x{};
int v;
foo<decltype(v)> y{};

你得到:

代码语言:javascript
复制
error: variable ‘foo<int&> x’ has initializer but incomplete type
 foo<decltype(*(int*)0)> x{};
                         ^
error: variable ‘foo<int> y’ has initializer but incomplete type
 foo<decltype(v)> y{};
                  ^

如您所见,decltype为取消引用的指针提供了int&,而为int变量v提供了int。

对于函数,他意味着返回lvalue的唯一方法是返回lvalue引用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64862374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档