64位G ++ 4.6.3不会将long视为专用函数模板中的long,即使它们的大小相同.这是一个错误吗?

Ose*_*Ose 1 c++ g++ template-specialization function-templates long-long

请考虑以下代码:

#include <iostream>
#include <cinttypes>  

template<class T>
void f();

template<>
inline void f<long long>() {
  std::cout<<"f<long long>()"<<std::endl;
}

int main(int , char** ) {
  std::cout<<"sizeof(long)="<<sizeof(long)<<std::endl;
  std::cout<<"sizeof(long long)="<<sizeof(long long)<<std::endl;
  f<int64_t>();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

32位G ++ 4.6.3成功编译并生成输出:

sizeof(long)=4
sizeof(long long)=8
f<long long>()
Run Code Online (Sandbox Code Playgroud)

但是,在64位G ++ 4.6.3下进行编译会产生链接器错误:

undefined reference to `void f<long>()'
ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

即使编译并运行f<int64_t>()注释掉的行产生:

sizeof(long)=8
sizeof(long long)=8
Run Code Online (Sandbox Code Playgroud)

有没有一个很好的理由为什么64位G ++对待f<long>f<long long>作为不同的功能,即使long并且long long大小相同,或者这是一个我应该报告的错误?

小智 7

底层类型int64_t可以是满足要求的任何东西.可以long在一个平台上和long long另一个平台上制作它.

由于您提供了专门化,long long并且通用版本没有正文,如果int64_t不是,long long您将获得未定义的引用.

是的,有一个很好的理由,为什么f<long>f<long long>不同的功能:这是因为标准说,long并且long long是不同的类型.它们碰巧在某个平台上的宽度相同并不重要,特别是因为它们在另一个平台上的宽度可能不同.