简体   繁体   English

如何从枚举模板参数中推导出数组大小?

[英]How to deduce array size from an enum template argument?

How should I change the code below so that Array<Index> array; 我应该如何更改下面的代码,以便Array<Index> array; is enough and the SIZE is automatically deduced from the enum? 足够了, SIZE会自动从枚举中推断出来吗?
Even if the enum changes, it is guaranteed that it contains SIZE referring to the correct 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;
}

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>. 更新:至于“Array <type>意味着你正在创建一个Type对象数组”(Jerry)和“类模板的名称有点误导”(Nawaz):实际上我正在创建CustomSqlQueryModel <TableColumns>。 The above is just a simplified code, nothing more. 以上只是一个简化的代码,仅此而已。 Jerry and Nawaz are rigth: this simplified code is unfortunate. Jerry和Nawaz很严格:这个简化的代码很不幸。

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: 每次定义新的枚举类型时,这需要一些额外的工作,但在用户代码中每次出现的Array <Index>都没有额外的工作:

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. 这样做的一个优点是,只要您知道如何获得最大尺寸,就可以专门设置您无法控制的外部枚举的特征。

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. ...如果作为Enum传递的类型不包含一些名为SIZE ,则实例化将不会编译。 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. 出于目的,你真的更喜欢Index是命名空间,但由于命名空间不是类型,我认为你不能将它用作模板参数。

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... 但是,我应该补充一点,我不确定我是否喜欢这个想法 - 大多数人都会认为Array<type>意味着你正在创建一个Type对象数组,这显然与那个完全不同...

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: 如果你只想要大小是模板参数,而不是类型 ,从你的例子看,数组的类型似乎总是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;
}

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<> . 注意这个补充:如果你也实现了const operator[] const版本,那么const Array<>可以使用它来访问数组元素,否则你的类不适用于const Array<>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM