2009-05-19 102 views
0

谁能向我解释为什么以下工作:为什么这个C++类不等同于这个模板?

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; 
} 

但这并不:

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; 
} 

显然,不仅仅是文本替换由参数模板更多的模板实例 - 这个魔术有简单的解释吗?

对于后者的编译器(克++ 4.1.2)吐出以下错误:

test.cxx:13: error: expected unqualified-id before '[' token 

其中线13是double[5] * ptr;线。

的问题不是:

“为什么MyClass的例子失败 - 因为C++不允许的Java风格的数组声明;-)?”。

但就是:

“为什么MyTemplateClass例如成功吗?”

+0

编译器是否吐出任何错误消息? – Tom 2009-05-19 16:15:02

回答

9

区别在于C++语法。一个简单的声明是这样形成:

declaration-specifier-seq init-declarator-list 

哪里声明说明符-SEQ是声明说明符的序列:

simple-type-specifier: int, bool, unsigned, typedef-name, class-name ... 
class-specifiers: class X { ... } 
type-qualifier: const, volatile 
function-specifier: inline, virtual, ... 
storage-class-specifier: extern, static, ... 
typedef 

你的想法。和init声明符列表是声明符为每个可选的初始化列表:

a 
*a 
a[N] 
a() 
&a = someObj 

所以,一个完整的简单的声明看起来是这样的,含有3说明符:

int a, &b = a, c[3] = { 1, 2, 3 }; 

类成员特殊规则来说明它们出现的不同背景,但它们非常相似。现在,你可以做

typedef int A[3]; 
A *a; 

因为首先使用的typedef符,然后简单类型说明符,然后像“一个[N]”说明符。然后第二个声明使用typedef名称“A”(简单类型说明符),然后使用“* a”之类的声明符。但是,当然不能做

int[3] * a; 

由于“INT [3]”不是有效的声明说明符-SEQ如上所示。

而现在,当然,模板是就像宏文本替换。当然,模板类型参数的处理方式与任何其他类型名称一样,只能解释为它所命名的类型,并且可以出现在简单类型说明符可以出现的位置。一些C#人倾向于说C++模板“就像宏”,但当然不是:)

3
template<class T> MyTemplateClass { 
    ... 
} 

更接近

template<class T> MyTemplateClass { 
    typedef {actual type} T; 
    ... 
} 

比简单的文本替换。

0

使用指针或指针数组有区别。在打算使用它之前,需要为阵列的每个元素分配内存,并且是在第二个示例中没有定义模板的情况下有错字。