如何更改下面的代码,以便Array<Index> array;
足够,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:至于“Array&lt; type&gt;意味着你正在创建一个Type对象数组”(Jerry)和“类模板的名称有点误导”(Nawaz):实际上我正在创建CustomSqlQueryModel&lt; TableColumns&gt;。以上只是一个简化的代码,仅此而已。 Jerry和Nawaz很严格:这个简化的代码很不幸。
答案 0 :(得分:6)
你可以写一个特质类。每次定义新的枚举类型时,这需要一些额外的工作,但每次出现的Array&lt; Index&gt;都不需要额外的工作。在用户代码中:
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;
}
这样做的一个优点是,只要您知道如何获得最大尺寸,就可以专门设置您无法控制的外部枚举的特征。
答案 1 :(得分:1)
如上所述,我认为你不能。但是,如果您将其更改为:
struct Index {
enum { X, Y, SIZE};
};
然后你的模板可能是这样的:
template <class Enum>
class Array {
// ...
private:
int array[Enum::SIZE];
};
...如果您作为Enum
传递的类型不包含一些名为SIZE
的正常量,则实例化将无法编译。出于目的,你真的更喜欢Index
是命名空间,但由于命名空间不是类型,我认为你不能将它用作模板参数。
Array<type>
意味着你正在创建一个Type
个对象的数组,并且这显然与那个完全不同......
答案 2 :(得分:0)
如果您只想将 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<>
可以使用它来访问数组元素,否则您的类将不适用于{{1} }。