Can somebody explain to me why the following works:
template<class T> class MyTemplateClass {
public:
T * ptr;
};
int main(int argc, char** argv) {
MyTemplateClass<double[5]> a;
a.ptr = new double[10][5];
a.ptr[2][3] = 7;
printf("%g\n", a.ptr[2][3]);
return 0;
}
But this doesn’t:
class MyClass {
public:
double[5] * ptr;
// double(*ptr)[5]; // This would work
};
int main(int argc, char** argv) {
MyClass a;
a.ptr = new double[10][5];
a.ptr[2][3] = 7;
printf("%g\n", a.ptr[2][3]);
return 0;
}
Obviously there is more to template instantiation than just a textual replacement by the arguments to the template – is there a simple explanation of this magic?
For the latter the compiler (g++ 4.1.2) spits out the following error:
test.cxx:13: error: expected unqualified-id before '[' token
Where line 13 is the double[5] * ptr; line.
The question is not:
“Why does the MyClass example fail? – because C++ doesn’t allow Java style array declarations ;-)”.
But is:
“Why does the MyTemplateClass example succeed?”
The difference lies in the C++ grammar. A simple-declaration is formed like this:
Where declaration-specifier-seq is a sequence of declaration specifiers:
You get the idea. And init-declarator-list is a list of declarators with an optional initializer for each:
So a full simple-declaration could look like this, containing 3 declarators:
Class members have special rules to account for the different context in which they appear, but they are very similar. Now, you can do
Since the first uses the typedef specifier and then simple-type-specifier and then a declarator like “a[N]”. The second declaration then uses the typedef-name “A” (simple-type-specifier) and then a declarator like “*a”. However, you of course cannot do
Since “int[3]” is not a valid declaration-specifier-seq as shown above.
And now, of course, a template is not just like a macro text substitution. A template type parameter of course is treated like any other type-name which is interpreted as just the type it names and can appear where a simple-type-specifier can appear. Some C# folks tend to say C++ templates are “just like macros”, but of course they are not 🙂