Ale*_*tov 135 c++ arrays reference
以下代码无法编译.
int a = 1, b = 2, c = 3;
int& arr[] = {a,b,c,8};
Run Code Online (Sandbox Code Playgroud)
C++标准对此有何看法?
我知道我可以声明一个包含引用的类,然后创建该类的数组,如下所示.但我真的想知道为什么上面的代码不能编译.
struct cintref
{
cintref(const int & ref) : ref(ref) {}
operator const int &() { return ref; }
private:
const int & ref;
void operator=(const cintref &);
};
int main()
{
int a=1,b=2,c=3;
//typedef const int & cintref;
cintref arr[] = {a,b,c,8};
}
Run Code Online (Sandbox Code Playgroud)
可以使用struct cintref
而不是const int &
模拟引用数组.
Kir*_*sky 138
回答关于标准的问题我可以引用C++标准§8.3.2/ 4:
不应引用引用,不引用引用数组,也不引用引用指针.
CB *_*ley 61
引用不是对象.他们没有自己的存储空间,只是引用现有的对象.因此,拥有引用数组是没有意义的.
如果你想要一个引用另一个对象的轻量级对象,那么你可以使用一个指针.struct
如果为所有struct
实例的所有引用成员提供显式初始化,则只能将带引用成员的a用作数组中的对象.参考文献不能默认初始化.
编辑:正如jia3ep所说,在声明的标准部分中,明确禁止引用数组.
gre*_*ggo 28
这是一个有趣的讨论.很明显,引用阵列是彻头彻尾的非法,但恕我直言的原因并不是说"它们不是对象"或"它们没有大小".我指出数组本身并不是C/C++中的完整对象 - 如果你反对,尝试使用数组作为"类"模板参数实例化一些stl模板类,看看会发生什么.您无法返回它们,分配它们,将它们作为参数传递.(数组参数被视为指针).但是制作数组数组是合法的.引用确实具有编译器可以且必须计算的大小 - 您不能sizeof()一个引用,但是您可以创建一个只包含引用的结构.它的大小足以包含实现引用的所有指针.如果不初始化所有成员,则无法实例化此类结构:
struct mys {
int & a;
int & b;
int & c;
};
...
int ivar1, ivar2, arr[200];
mys my_refs = { ivar1, ivar2, arr[12] };
my_refs.a += 3 ; // add 3 to ivar1
Run Code Online (Sandbox Code Playgroud)
实际上,您可以将此行添加到结构定义中
struct mys {
...
int & operator[]( int i ) { return i==0?a : i==1? b : c; }
};
Run Code Online (Sandbox Code Playgroud)
...现在我有一些看起来很像refs数组的东西:
int ivar1, ivar2, arr[200];
mys my_refs = { ivar1, ivar2, arr[12] };
my_refs[1] = my_refs[2] ; // copy arr[12] to ivar2
&my_refs[0]; // gives &my_refs.a == &ivar1
Run Code Online (Sandbox Code Playgroud)
现在,这不是一个真正的数组,它是一个运算符重载; 例如,它不会像数组(arr)/ sizeof(arr [0])那样做数组通常做的事情.但它完全符合我想要的一系列引用,完全合法的C++.除了(a)设置超过3或4个元素是痛苦的,并且(b)它使用一堆?进行计算:这可以使用索引来完成(而不是使用正常的C指针计算语义索引) ,但仍然索引).我希望看到一个非常有限的"引用数组"类型,它实际上可以做到这一点.即一个引用数组不会被视为引用的一般数组,而是它将是一个新的"引用数组",它有效地映射到类似于上面的内部生成的类(但是你很遗憾无法用模板制作).
这可能会有用,如果你不介意这种讨厌:重新'*this'作为int*的数组并返回一个引用:(不推荐,但它显示了正确的'数组'会工作):
int & operator[]( int i ) { return *(reinterpret_cast<int**>(this)[i]); }
Run Code Online (Sandbox Code Playgroud)
You*_*ouw 27
评论您的编辑:
更好的解决方案std::reference_wrapper
.
详细信息:http: //www.cplusplus.com/reference/functional/reference_wrapper/
例:
#include <iostream>
#include <functional>
using namespace std;
int main() {
int a=1,b=2,c=3,d=4;
using intlink = std::reference_wrapper<int>;
intlink arr[] = {a,b,c,d};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
EFr*_*aim 12
数组可以隐式转换为指针,而指向引用的指针在C++中是非法的
nav*_*tor 10
因为许多人在这里说过,引用不是对象.它们只是别名.确实有些编译器可能会将它们实现为指针,但标准不会强制/指定它.因为引用不是对象,所以你不能指向它们.在数组中存储元素意味着存在某种索引地址(即指向某个索引处的元素); 这就是为什么你不能有引用数组的原因,因为你不能指向它们.
请改用boost :: reference_wrapper或boost :: tuple; 或只是指针.
鉴于int& arr[] = {a,b,c,8};
,是什么sizeof(*arr)
?
在任何其他地方,引用被视为仅仅是事物本身,所以sizeof(*arr)
应该简单地说sizeof(int)
.但这会使这个数组上的数组指针算法运算错误(假设引用的宽度不同于整数).为消除歧义,这是禁止的.
我相信答案非常简单,它与引用的语义规则以及在 C++ 中如何处理数组有关。
简而言之:引用可以被认为是没有默认构造函数的结构,因此所有相同的规则都适用。
1) 从语义上讲,引用没有默认值。引用只能通过引用某些东西来创建。引用没有表示没有引用的值。
2) 当分配一个大小为 X 的数组时,程序会创建一个默认初始化对象的集合。由于引用没有默认值,创建这样的数组在语义上是非法的。
此规则也适用于没有默认构造函数的结构/类。以下代码示例无法编译:
struct Object
{
Object(int value) { }
};
Object objects[1]; // Error: no appropriate default constructor available
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
90113 次 |
最近记录: |