如何将一系列const变量作为const数组访问

时间:2018-02-20 09:17:23

标签: c++

很明显我可以:

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个? 是否有任何内存开销?

那么哪种方式最好? 两种方法都可行吗?

注意:当然也有使用指针数组的选项 - 但目标是找到一种只有引用的方法。

2 个答案:

答案 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指针的额外内存开销(如果您计划有许多变量,这可以忽略不计)。并且还会有运行时开销 - 两个静态强制转换,一个整数乘法和一个加法,但这将具有您瞄准的访问语法,并且不会复制变量。