设计一个文字类型class,里面有一个变体字段,里面可以存储一个或三个对象

Designing a literal-type class with a variant field inside in which one or three objects may be stored

我正在尝试设计一个 class - 为了便于讨论,我们称之为 A - 它将满足一组特定的要求:

  1. A 必须是文字类型,以允许编译器在编译时通过 constexpr 构造函数初始化其全局实例(许多这种类型的全局 const 对象是在源代码)。这样做的原因是 A 在整数上采用了简单的编译时加密(主要是 XOR)。解密稍后在运行时完成,同时访问适当的 int.
  2. 它的中央私有字段是一个简单的整数。但是,class 有两个构造函数: A::A(int x)A::A(int x, int y, int z)。如果调用第一个版本,那么稍后,在运行时,只要进行需要使用它的方法调用,class 就会在内部使用该单个 x。相反,如果使用具有三个参数的第二个版本,则在调用需要一个的函数时将在运行时决定使用xyz中的哪一个。
  3. A必须是单一类型;第一个构造函数的一种类型和第二个构造函数的另一种类型并不令人满意(A 经常作为参数传递给函数,因此如果没有此约束,我将需要复制或模板化所有这些函数)。
  4. 绝大部分A对象都会是全局常量,很少会发生赋值,即使发生也肯定不会在三个int的对象和一个对象之间与一个 int 反之亦然。

总结一下:A 将被实例化为全局 const 对象。如果我用单个 int 初始化一个对象,那么单个 int 应该存储在其中(仅此而已)。如果我用三个 int 初始化它,那么这三个 int 应该存储在里面。无需担心从三 int 对象到一个 int 对象的赋值,反之亦然,因为它们都是常量。

目前我考虑的解决方案如下:


问题: 对于我错过的这个问题,是否有一个优雅的解决方案,或者我是否必须选择我在上面考虑过(并拒绝)的解决方案之一? 我的平台是 VC++,所以使用 C++11/4 是可以的,除了一些更深奥的部分,但是 C++17 草稿中的功能还不可用。

有 2 个成员的 class/struct?

指向 intbool 的指针(布尔值表示指针指向一个或三个值)?

#include <iostream>

struct foo
 {
   bool           single;
   int const    * p;

   constexpr foo ( int const & x ) : single{true}, p{&x}
    {}

   constexpr foo ( int const * y ) : single{false}, p{y}
    {}
 };

constexpr int x{2};
constexpr int y[]{3, 5, 7};

int main ()
 {
   constexpr foo f1{x};
   constexpr foo f3{y};
 }

似乎您可以使用的最好的东西是有条件的整数范围:

class A {
    std::array<int, 3> data;
    bool one;

public:
    constexpr A(int x): data{{x, 0, 0}}, one(true) { }
    constexpr A(int x, int y, int z): data{{x, y, z}}, one(false) { }

    constexpr size_t size() const { return one ? 1 : 3; }
    constexpr const int* begin() const { return data.data(); }
    constexpr const int* end() const { return data.data() + size(); }
};

我不完全确定你选择哪个元素的逻辑是什么,但如果你有一个 1 尺寸的范围,你会得到那个元素,如果你有一个 3 尺寸的范围,那么你会做任何事情你需要做的。


不管具体细节如何,重点是你想要一个有3个int和一个bool的类型。您需要存储 3 int,您希望它是字面值,并且您希望它知道它存储的是 3 还是 1 int。这几乎说明了类型。剩下的唯一事情就是确定您希望数据访问的外观如何,而这并没有指定。