为什么以下工作C++
,我认为ODR
规则会出现在以下代码中
typedef char int8;
class Sample {
public:
template <typename T>
void test( T param){
}
};
int main() {
Sample s;
s.test<char>('a');
s.test<int8>((int8)'b');
return 0;
}
为什么以下工作C++
,我认为ODR
规则会出现在以下代码中
typedef char int8;
class Sample {
public:
template <typename T>
void test( T param){
}
};
int main() {
Sample s;
s.test<char>('a');
s.test<int8>((int8)'b');
return 0;
}
因为当模板实例化完成并且编译器摆脱了 typedef 和不必要的强制转换时,您的代码与以下内容完全相同:
class Sample {
public:
void test(char param){
}
};
int main() {
Sample s;
s.test('a');
s.test('b');
return 0;
}
您似乎认为 atypedef
声明了另一种不同的类型,但事实并非如此。它只是一个别名(通常是为了您的方便)。OTOH,当您调用具有不同模板参数的函数模板时,会生成具有不同签名的函数。在这两种情况下都没有违反 ODR。
它两次都在做同样的事情。只是看起来他们不一样。
第一个说它将使用该char
版本,因此 T 变为char
.
第二个说它将使用该int8
版本,因此 T 将成为 an int8
,这实际上只是 achar
变相。因此, T 仍然是一个字符,并且在这两种情况下你都传递了一个字符,所以一切都很好。