C++ C++;模板与ODR规则

C++ C++;模板与ODR规则,c++,C++,为什么下面的代码在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

为什么下面的代码在
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 char int8;
类样本{
公众:
模板
孔隙试验(T参数){
}
};
int main(){
样本s;
s、 测试(‘a’);
s、 测试((int8)“b”);
返回0;
}

它两次都在做同样的事情。只是看起来他们不一样

第一个表示它将使用
char
版本,因此T变成
char


第二个表示它将使用
int8
版本,因此T将变成
int8
,这实际上只是一个伪装的
char
。因此,T仍然是一个字符,并且您在这两种情况下都传递了一个字符,所以一切都很好。

因为当模板实例化完成并且编译器摆脱typedef和不必要的强制转换时,您的代码与:

class Sample {
public:
  void test(char param){
  }
};

int main() {
  Sample s;
  s.test('a');
  s.test('b');
  return 0;
}

您似乎认为
typedef
声明了另一种不同的类型,但事实并非如此。这只是一个别名(通常是为了方便起见)。OTOH,当您使用不同的模板参数调用函数模板时,将生成具有不同签名的函数。在这两种情况下都没有违反ODR。

怎么了?你认为什么是正确的行为?为什么?只有一个实例化,
void测试(charparam)否,typedef只是同一类型的另一个名称。只有一个版本。您可以很容易地测试这一点:如果int8与char相同,那么只有一个定义和实例化。违反ODR的情况在哪里?如果int8不同于char,那么有两种不同的实例化。那么违反ODR的地方在哪里呢?