gpt4 book ai didi

c++ - 为什么这个 C++ 类不等同于这个模板?

转载 作者:太空宇宙 更新时间:2023-11-04 14:43:02 24 4
gpt4 key购买 nike

有人可以向我解释为什么以下方法有效吗:

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

显然,模板实例化不仅仅是通过模板参数进行文本替换 - 是否有关于这种魔法的简单解释?

对于后者,编译器 (g++ 4.1.2) 会报出以下错误:

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

第 13 行是 double[5] * ptr; 行。

问题不是:

“为什么 MyClass 示例会失败?- 因为 C++ 不允许 Java 样式数组声明 ;-)”。

但是是:

“MyTemplateClass 示例为什么会成功?”

最佳答案

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

declaration-specifier-seq init-declarator-list

其中 declaration-specifier-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-declarator-list 是一个声明符列表,每个声明符都有一个可选的初始值设定项:

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

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

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

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

typedef int A[3];
A *a;

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

int[3] * a;

因为“int[3]”不是有效的声明说明符序列,如上所示。

现在,当然,模板只是一个宏文本替换。模板类型参数当然像任何其他类型名称一样被对待,它被解释为它命名的类型并且可以出现在简单类型说明符可以出现的地方。一些 C# 人员倾向于说 C++ 模板“就像宏一样”,但它们当然不是 :)

关于c++ - 为什么这个 C++ 类不等同于这个模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/883682/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com