Рассмотрим следующий код:
#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;
}
32-битный G ++ 4.6.3 успешно компилирует это и выдает:
sizeof(long)=4
sizeof(long long)=8
f<long long>()
Однако компиляция под 64-битную версию G ++ 4.6.3 приводит к ошибке компоновщика:
undefined reference to `void f<long>()'
ld returned 1 exit status
хотя компилирование и запуск с f<int64_t>()
Закомментированная строка производит:
sizeof(long)=8
sizeof(long long)=8
Есть ли веская причина, почему 64-битный G ++ лечит f<long>
а также f<long long>
как разные функции, хотя long
а также long long
одного размера, или это ошибка, о которой я должен сообщить?
Основной тип int64_t
может быть все, что соответствует требованиям. Это нормально, чтобы сделать это long
на одной платформе и long long
по другому.
Поскольку вы предоставляете специализацию для long long
и универсальная версия не имеет тела, если int64_t
это не long long
Вы получаете неопределенную ссылку.
И да, есть веская причина, почему f<long>
а также f<long long>
разные функции: это потому, что стандарт говорит, что long
а также long long
разные типы. Тот факт, что на одной платформе они имеют одинаковую ширину, не имеет значения, особенно потому, что на другой они могут иметь разную ширину.
Они разных типов, поэтому к ним нужно относиться по-разному. Размер типов не влияет на перегрузку или выбор шаблона.
Ваша проблема может быть в том, что int64_t
является long
на одной системе и long long
с другой. Это проблема при объединении typedef с перегрузками или шаблонами.