Typedef compilation error on function overload
Why can't I compile the program 1 when the the program 2 is working fine ? Why is it's behavior different?
Program 1:
#include <iostream>
typedef int s1;
typedef int s2;
void print(s1 a){ std::cout << "s1\n"; }
void print(s2 a){ std::cout &开发者_JS百科lt;< "s2\n"; }
int main() {
s1 a;
s2 b;
print(a);
print(b);
return 0;
}
Program 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;
}
This is a bug reproduce from templated class, How can I verify if two template argument are from the same type (in the case of the program 1)
Typedefs don't define new types, they merely create aliases for existing types. In your first program s1
and s2
are both aliases for int
. In your second program they are aliases for two different structures that just happen to be identical in structure.
You could have assigned names to the two structures which would have made this clearer:
// Semantically identical to program 2
typedef struct a {int a;} s1;
typedef struct b {int a;} s2;
On the other hand if you made them aliases for the same type then the second program would fail just like the first:
// Different from program 2. This will draw a compile error.
struct s {int a;};
typedef struct s s1;
typedef struct s s2;
int
is a primitive type: no matter where you use it, it will always refer to exactly the same thing - an int
.
struct{int a;}
is not a primitive type - each time you define a struct{int a;}
, you're creating a new type - hence why s1
and s2
are considered distinct in your Program 2 case.
For instance, consider the following:
typedef struct{int count;} apples;
typedef struct{int count;} airplanes;
Are apples and airplanes the same thing? Probably not. But their counts are both numerical counts. Hence why int
is consistent but structs
are not - int
has no context associated with it, structs do.
typedef
doesn't actually make any new types - it only aliases a type under another name.
Therefore, the difference between Program 1 and Program 2 is that in Program 1, you're attempting to define two versions of a function with (as far as the compiler is concerned) exactly the same signature: print(int)
. In Program 2, you're defining two different signatures: print([first struct type])
and print([second struct type])
.
The difference is that in program 1, s1
and s2
are aliases of the same type, whereas in program 2 they're different types. You can't define two overloads of a function with the same signature, even if you use different type names to produce that signature.
精彩评论