数组和右值

13

$4.2/1 - "类型为“数组of N T”或“未知边界的T数组”的左值或右值可以转换为类型为“指向T的指针”的右值。 结果是一个指向数组的第一个元素的指针。"

我不确定除了在初始化/声明期间,我们如何获得数组类型的右值?


3
可能是重复问题:我认为我找到了一个数组类型的右值示例 - Ben Voigt
4个回答

19

在这个上下文中,我不确定你所指的“初始化/声明”是什么意思。以下内容中,该数组是一个prvalue。

template<typename T> using alias = T;

int main() { return alias<int[]>{1, 2, 3}[0]; }

这可以通过decltype(alias<int[]>{1, 2, 3})来验证,它的类型为int[3]。这种即兴创建数组的方式最初并不打算起作用,但通过与统一初始化相关的工作而意外地溜进了工作草案中。当我意识到C++0x工作草案中的某些段落禁止在即兴创建数组临时对象时出现某些特殊情况,而其他段落则允许它时,我向C++委员会发送了一个缺陷报告,然后基于GCC的部分工作实现决定全面支持它。


更具体地说,在当前的措辞中,f().array 是一个 xvalue,对吗?我认为不可能得到一个数组 prvalue,对吗? - ABu
2
@Peregring-lk 是的,现在它是一个xvalue(回答时不是)。在alias<int[]>{1, 2, 3}中,表达式既是xvalue又是prvalue。首先,它是一个没有关联对象的prvalue,当您对其进行索引时,“实例化转换”会为其创建一个对象并赋予表达式值类别“xvalue”,然后取指向数组第一个元素的指针。 - Johannes Schaub - litb

1

你不能获取数组类型的rvalue。数组只能是lvalue,并且每当它们用作lvalue时,它们都会衰减为指向第一个元素的指针。

int array[10];
int * p = array; // [1]

[1] 中的表达式array是类型为int (&)[10]的lvalue,它被转换为类型为int *p的rvalue,也就是说,具有N==10 T==int的rvalue int数组 被转换为类型为T==int的指针的lvalue。


你能否给我展示一个例子,其中以上引用适用于 Array 类型的 Rvalue? - Chubsdad
函数不能返回数组类型,这是原因吗? - Cedric H.
1
@Cedric H.:在§8.3.5[dcl.fct]/3中,标准规定确定每个参数的类型后,任何类型为“T数组”或“返回T的函数”的参数都将被调整为“指向T的指针”或“指向返回T的函数的指针”,分别。也就是说,标准规定void foo(char [10])是一个声明,与void foo(char*)完全等效--这是针对参数的。然后在§8.3.5/6中,它说:函数不应该有类型为数组或函数的返回类型,尽管它们可以有类型为指向这些东西的指针或引用的返回类型。 - David Rodríguez - dribeas
我给这个点了踩,因为它是错误的。你可以有数组类型的rvalue。 - Johannes Schaub - litb
1
@litb:你能提供一个数组类型的rvalue表达式的例子,它不会衰减为指针吗? - David Rodríguez - dribeas
1
@David Rodríguez - dribeas 这里:"12"- 左值字符串,{'1','2','\0'} - 右值字符数组。https://godbolt.org/z/lIcRbX 似乎 MSVC2017 即使在15.9.6 版本中也无法正确编译它,但旧版的 gcc/clang 可以! - Andry

0

获取数组正确的引用值非常容易,对于类引用属性将被添加到其成员中。

struct s {
    int arr[5];
};
using array_right_reference = decltype((s().arr));
static_assert(std::is_same<array_right_reference, int (&&)[5]>::value, "");

-2

这个有机会展示数组 Rvalue 吗?

int main(){
 int buf[10][10];

 int (*p)[10] = buf;

 int (*p2)[10] = p;      // LValue to Rvalue conversion of Array type 'p'
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接