为什么我不能在程序2工作正常时编译程序1?为什么它的行为不同?
计划1:
#include <iostream>
typedef int s1;
typedef int s2;
void print(s1 a){ std::cout << "s1\n"; }
void print(s2 a){ std::cout << "s2\n"; }
int main() {
s1 a;
s2 b;
print(a);
print(b);
return 0;
}
计划2:
#include <iostream>
typedef struct{int a;} s1;
typedef struct{int a;} s2;
void print(s1 a){ std::cout << "s1\n"; }
void print(s2 a){ std::cout << "s2\n"; }
int main() {
s1 a;
s2 b;
print(a);
print(b);
return 0;
}
这是从模板类重现的错误,如何验证两个模板参数是否来自同一类型(在程序1的情况下)
答案 0 :(得分:10)
Typedef不定义新类型,它们只是为现有类型创建别名。在您的第一个程序中s1
和s2
都是int
的别名。在你的第二个程序中,它们是两个不同结构的别名,结构恰好相同。
您可以为这两个结构指定名称,这样可以更清楚:
// Semantically identical to program 2
typedef struct a {int a;} s1;
typedef struct b {int a;} s2;
另一方面,如果你为相同的类型创建了别名,那么第二个程序就会像第一个程序一样失败:
// Different from program 2. This will draw a compile error.
struct s {int a;};
typedef struct s s1;
typedef struct s s2;
答案 1 :(得分:2)
int
是一种原始类型:无论你在哪里使用它,它总是会引用完全相同的东西 - int
。
struct{int a;}
不是原始类型 - 每次定义struct{int a;}
时,您都会创建一个新类型 - 因此s1
和s2
被认为是不同的你的计划2案例。
例如,请考虑以下事项:
typedef struct{int count;} apples;
typedef struct{int count;} airplanes;
苹果和飞机是一样的吗?可能不是。但他们的数量都是数字计数。因此,为什么int
是一致的,但structs
不是 - int
没有与之关联的上下文,结构就是这样。
typedef
实际上并没有创建任何新类型 - 它只是用另一个名称别名一个类型。
因此,程序1和程序2之间的区别在于,在程序1中,您试图定义一个函数的两个版本(就编译器而言)完全相同的签名:print(int)
。在计划2中,您要定义两个不同的签名:print([first struct type])
和print([second struct type])
。
答案 2 :(得分:0)
不同之处在于,在程序1中,s1
和s2
是相同类型的别名,而在程序2中,它们是不同的类型。即使使用不同的类型名称来生成该签名,也无法使用相同的签名定义函数的两个重载。