Давно имелись подозрения, что не всё гладко в реализации шаблонов в компиляторе Borland'a (bcc32, Borland C++ Compiler). Borland благополучно отошёл от разработки компиляторов, предоставив свои детища CodeGear'у. Те немного подретушировали компилятор, подправив в нём откровенные несоответствия современным стандартам С++ (добавив, в частности, поддержку неименованных union как в MSVC++), но некоторые проблемы с реализацией шаблонов всё же остались.
Одна из них заключается в том, что приведенный ниже код не компилируется компилятором bcc32.
Читать дальше... //------------------------------------------------------------ template <class T, int Value> class A { public: union { T a[Value]; char b[Value * sizeof(T)]; } };
int main() { A<int, 1> Obj; Obj.b[0] = 1; Obj.b[1] = 0; Obj.b[2] = 0; Obj.b[3] = 0; cout << Obj.a[0] << endl; return 0; } //------------------------------------------------------------
|
Компилятор заявляет, что невозможно вычислить sizeof(T) (хотя тип T известен на стадии компиляции), и что Value является неопределенным идентификатором. На самом деле, компилятор заблуждается, а проблема заключается в том, что он не может вычислить математическое выражение, подставленное в качестве размера массива. Оказывается, если вычислить выражение, объявив enum, то всё будет нормально. Так же, через объявление enum, решается проблема с "неопределенностью" Value.
Перепишем код.
//------------------------------------------------------------ template <class T, int Value> class A { public: enum {__Value = Value }; enum {__Size = Value * sizeof(T)}; union { T a[__Value]; char b[__Size]; } };
int main() { A<int, 1> Obj; Obj.b[0] = 1; Obj.b[1] = 0; Obj.b[2] = 0; Obj.b[3] = 0; cout << Obj.a[0] << endl; return 0; } //------------------------------------------------------------
|
Теперь код компилируется и выполняется.
Приведенная выше проблема является одним из камней преткновения, вследствие которых Qt 4 не компилируется компиляторами bcc32.