0

我想使用负数组索引来访问结构中紧接在该数组之前的相同类型成员。

考虑这种类型的代码:

union hello {
    int a[2];
    struct { int b0; int b1[1]; };
};

我想用来b1[-1]访问b0.

当我尝试这样做时,clang 和 gcc 似乎完全理解我想要什么。

extern const int test = hello{{42, 1337}}.b1[-1];

这在编译时正确地确定test42.

-1不幸的是,clang 会产生一个不受约束的警告。const如果我更改为.gcc 也会这样做constexpr

编写此类代码的正确方法是什么?

以下是我已经知道但不喜欢的方式:

  • a[]与基于 1 的索引一起使用。
  • 制作b1一个指向 的指针a[1]
4

2 回答 2

0

当我尝试这样做时,clang 和 gcc 似乎完全明白我想要什么

是的,但如果被问到(gcc),它们也会产生一些诊断:

prog.cc:6:33:警告:ISO C++ 禁止匿名结构 [-Wpedantic]
     结构{int b0; 诠释 b1[1]; };

此外,访问b1不是联合的活动成员(a是初始化的成员)是未定义的行为。

您可以改为编写一个封装数据和所需访问逻辑的类:

#include <iostream>
#include <array>

template<size_t Dim>
class Hello
{
    std::array<int, Dim> data_;
public:
    template<class... ArgType>
    constexpr Hello(ArgType... args) : data_{args...} {};

    constexpr int first()       const noexcept { return data_[0]; }

    constexpr int one_based(int i) const { return data_.at(i + 1); }
    constexpr int zero_based(int i) const { return data_.at(i); }
};

int main()
{
    constexpr Hello<2> hi {42, 1337};

    static_assert(hi.first() == 42);

    static_assert(hi.one_based(-1) == 42);
    static_assert(hi.one_based(0) == 1337);

    static_assert(hi.zero_based(0) == 42);
    static_assert(hi.zero_based(1) == 1337);

    std::cout << "So far, so good...\n";
}
于 2018-11-15T16:32:36.060 回答
0

如果我正确理解您的问题,您有变量 {c 0 , c 1 , c 2 , c 3 ,...},有时您想将它们视为数组 [c 1 , c 2 , c 3 ,.. .],其他时候作为数组 [c 0 , c 1 , c 2 , c 3 ,...]。

(我不确定我理解你为什么要这样做,但没关系。)

这是一个解决方案:

int A[5];
int *B = A+1;
A[0] = c0;
A[1] = c1;
A[2] = c2;
....

现在,如果要包含 c 0 ,则可以遍历 A[i] ,如果不包含则可以遍历B[i] 。

于 2018-11-15T01:08:58.503 回答