函数重载时的Typedef编译错误

时间:2010-02-26 02:57:26

标签: c++ overloading typedef

为什么我不能在程序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的情况下)

3 个答案:

答案 0 :(得分:10)

Typedef不定义新类型,它们只是为现有类型创建别名。在您的第一个程序中s1s2都是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;}时,您都会创建一个新类型 - 因此s1s2被认为是不同的你的计划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中,s1s2是相同类型的别名,而在程序2中,它们是不同的类型。即使使用不同的类型名称来生成该签名,也无法使用相同的签名定义函数的两个重载。