为什么以下内容适用于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;
}
答案 0 :(得分:2)
因为当完成模板实例化并且编译器摆脱了typedef和不必要的强制转换时,你的代码与以下内容完全相同:
class Sample {
public:
void test(char param){
}
};
int main() {
Sample s;
s.test('a');
s.test('b');
return 0;
}
您似乎认为typedef
声明了另一种不同的类型,但事实并非如此。它只是一个别名(通常是为了你的方便)。 OTOH,当您使用不同的模板参数调用函数模板时,会生成具有不同签名的函数。在任何一种情况下都没有ODR违规。
答案 1 :(得分:1)
两次都做同样的事情。它看起来好像不一样。
第一个说它会使用char
版本,因此T变为char
。
第二个说它会使用int8
版本,所以T会变成int8
,实际上只是伪装成char
。因此,T仍然是一个char,在这两种情况下你都传递了一个char,所以一切都很好。