很明显我可以:
const TYPE a();
const TYPE b();
const TYPE c();
我可以
const TYPE all[] = {
TYPE(),
TYPE(),
TYPE(),
};
但我希望同时拥有 - 直接访问和数组访问。
无论如何,内存布局应该是相同的。我想到了union
的想法。有点像:
union FOO {
struct index_t {
TYPE a;
TYPE b;
TYPE c;
} index;
TYPE all[];
};
const FOO foo;
foo.index.a;
foo.all[0];
天真的方法是只使用数组中的引用
const TYPE a();
const TYPE b();
const TYPE c();
const TYPE all[3] = {
a,
b,
c,
};
问题是:我能确定这些仅仅是3个实例,还是有一些复制将它们变成6个? 是否有任何内存开销?
那么哪种方式最好? 两种方法都可行吗?
注意:当然也有使用指针数组的选项 - 但目标是找到一种只有引用的方法。
答案 0 :(得分:1)
数组是一系列变量(技术上是对象,但这里的区别并不重要)。你不需要另一个。
TYPE all[3]; // use std::array instead if you can
这就是所需要的。 const
在这里没有特别重要的意义,可以根据需要添加或删除它。
现在,如果您对语法糖的渴望以及希望将all[0]
别名为a
等,这是可能的,但这种可能性可能会带来成本。
TYPE &a=all[0], &b=all[1], &c=all[2];
编译器可能会为a,b和c分配存储空间,尤其是当它们是类中的成员时(这是您的成本)。当它们是静态或自动变量时,它可能会或可能不会将它们优化掉。
应该强调的是,a,b和c不是需要。它们只是为现有对象all[i]
提供备用名称。
实现此目标的另一种方法如下
inline TYPE & a() { return all[0]; } // etc
这不太可能有任何运行时成本,因为编译器非常擅长优化这些简单的功能。缺点是你需要写a()
而不是a
。
union方法,即使你设法让它为你工作,是危险的,不推荐,因为它必然会调用未定义的行为。
答案 1 :(得分:0)
您可以拥有以下内容:
struct FOO {
struct INDEX {
const TYPE a; // Can even initialize in place, e.g. const int a = 8;
const TYPE b;
const TYPE c;
};
// From here on boilerplate
Index index;
FOO() : all{this} {}
struct ALL {
ALL(FOO* p): parent{p} {}
const TYPE& operator[](unsigned index) {
// Some pointer magic
return *(static_cast<TYPE*>(static_cast<void*>(parent) + index * sizeof(TYPE)));
}
FOO* parent;
};
ALL all;
};
您将只有parent
指针的额外内存开销(如果您计划有许多变量,这可以忽略不计)。并且还会有运行时开销 - 两个静态强制转换,一个整数乘法和一个加法,但这将具有您瞄准的访问语法,并且不会复制变量。