如何从枚举模板参数推断数组大小?

发布于 2024-10-17 13:01:42 字数 662 浏览 2 评论 0原文

我应该如何更改下面的代码,以便 Arrayarray; 就足够了,SIZE 是从枚举中自动推导出来的?
即使枚举发生变化,也能保证它包含引用正确大小的SIZE

template <typename Enum, int N>
class Array {

public:
    int& operator[](Enum index) { return array[index]; }

private:
    int array[N];
};

enum Index { X, Y, SIZE };

int main() {

    Array<Index, SIZE> array;

    array[X] = 1;

    return 0;
}

更新:至于“Array意味着您正在创建 Type 对象的数组”(Jerry)和“类模板的名称有点误导”(Nawaz):实际上我正在创建 CustomSqlQueryModel。上面只是一个简化的代码,仅此而已。 Jerry 和 Nawaz 是对的:这个简化的代码是不幸的。

How should I change the code below so that Array<Index> array; is enough and the SIZE is automatically deduced from the enum?
Even if the enum changes, it is guaranteed that it contains SIZE referring to the correct size.

template <typename Enum, int N>
class Array {

public:
    int& operator[](Enum index) { return array[index]; }

private:
    int array[N];
};

enum Index { X, Y, SIZE };

int main() {

    Array<Index, SIZE> array;

    array[X] = 1;

    return 0;
}

UPDATE: As for "Array<type> means you're creating an array of Type objects" (Jerry) and "the name of class template is a bit misleading" (Nawaz): actually I am creating CustomSqlQueryModel<TableColumns>. The above is just a simplified code, nothing more. Jerry and Nawaz are rigth: this simplified code is unfortunate.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

兔小萌 2024-10-24 13:01:42

您可以编写一个特征类。每次定义新的枚举类型时,这都需要一些额外的工作,但每次出现 Array时不需要额外的工作。在用户代码中:

template<class Enum>
struct ArrayTraits;

template<class Enum>
struct Array {
  int& operator[](Enum index) { return array[index]; }

private:
  int array[ArrayTraits<Enum>::size];
};

enum Index { X, Y, SIZE };

template<>
struct ArrayTraits<Index> {
  enum { size = SIZE };
};


int main() {
  Array<Index> array;
  array[X] = 1;
  return 0;
}

这样做的优点之一是,只要您知道如何获取最大大小,您就可以专门化您无法控制的外部枚举的特征。

You can write a traits class. This requires a bit of extra work each time you define a new enum type, but no extra work for each occurrence of Array<Index> in user code:

template<class Enum>
struct ArrayTraits;

template<class Enum>
struct Array {
  int& operator[](Enum index) { return array[index]; }

private:
  int array[ArrayTraits<Enum>::size];
};

enum Index { X, Y, SIZE };

template<>
struct ArrayTraits<Index> {
  enum { size = SIZE };
};


int main() {
  Array<Index> array;
  array[X] = 1;
  return 0;
}

One of the advantages of this is you can specialize the traits for external enums you don't control, as long as you know how to get the max size.

删除→记忆 2024-10-24 13:01:42

如前所述,我认为你不能。但是,如果您将其更改为:

struct Index { 
    enum { X, Y, SIZE};
};

那么您的模板可能类似于:

template <class Enum>
class Array { 
// ...

private:
    int array[Enum::SIZE];
};

...并且如果您作为 Enum 传递的类型不包含一些名为 SIZE< 的正常量/code>,实例化将无法编译。出于当前的目的,您确实更喜欢 Index 是一个命名空间,但由于命名空间不是一种类型,我认为您不能将它用作模板参数。

不过,我应该补充一点,我不确定我是否喜欢这个想法——大多数人会认为 Array 意味着您正在创建一个 Type< 的数组/code> 对象,这显然与那个完全不同......

As stated, I don't think you can. If, however, you change it to something like:

struct Index { 
    enum { X, Y, SIZE};
};

Then your template could be something like:

template <class Enum>
class Array { 
// ...

private:
    int array[Enum::SIZE];
};

...and if the type you pass as Enum doesn't include some positive constant named SIZE,the instantiation won't compile. For the purpose at hand, you'd really kind of prefer that Index was a namespace, but since a namespace isn't a type, I don't think you can use it as a template argument.

I should add, however, that I'm not sure I like this idea at all -- most people are going to think Array<type> means you're creating an array of Type objects, and this is clearly something entirely different from that...

泪之魂 2024-10-24 13:01:42

如果您只想将 size 作为模板参数,而不是 type ,从您的示例来看,数组的 type 似乎是总是 int,那你为什么不实现这个:

template <int size>
class Array {

public:
    int& operator[](int index) { return array[index]; }

    //Note this addition!
    int operator[](int index) const { return array[index]; }
private:
    int array[size];
};

int main() {

    Array<10> array;

    array[0] = 1;
    array[1] = 2;

    return 0;
}

注意这个补充:如果你也实现 operator[] 的 const 版本会更好,这样 const Array< ;> 可以使用它来访问数组元素,否则您的类将无法用于 const Array

If you want only the size to be template argument, not the type , as from your example it seems that the type of the array would be always int, then why don't you implement this:

template <int size>
class Array {

public:
    int& operator[](int index) { return array[index]; }

    //Note this addition!
    int operator[](int index) const { return array[index]; }
private:
    int array[size];
};

int main() {

    Array<10> array;

    array[0] = 1;
    array[1] = 2;

    return 0;
}

Note this addition: it's better if you implement const version of operator[] too, so that const Array<> can use it to access the array elements, otherwise your class wouldn't work for const Array<>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文