I have a template function with a single parameter <T>, and I would like to specialize this function for different integral types. At first this seemed obvious, but after several attempts, I found that I really do not understand how specialization really works here, and how to achieve some degree of portability ...
Here's the test program:
#include <iostream>
#include <typeinfo>
template <typename T> void foo() { std::cout << " foo<T> with T=" << typeid(T).name() << '\n'; }
template <> void foo<int>() { std::cout << " foo<int>\n"; }
template <> void foo<long>() { std::cout << " foo<long>\n"; }
template <> void foo<long long>() { std::cout << " foo<long long>\n"; }
template <> void foo<size_t>() { std::cout << " foo<size_t>\n"; }
int main () {
std::cout << "sizeof(int)=" << sizeof(int) << ", ";
std::cout << "sizeof(long)=" << sizeof(long) << ", ";
std::cout << "sizeof(long long)=" << sizeof(long long) << ", ";
std::cout << "sizeof(size_t)=" << sizeof(size_t) << "\n";
foo<int>();
foo<long>();
foo<long long>();
foo<size_t>();
foo<ssize_t>();
foo<int8_t>();
foo<int16_t>();
foo<int32_t>();
foo<int64_t>();
foo<uint32_t>();
foo<uint64_t>();
return 0;
}
and on my machine he produces
sizeof(int)=4, sizeof(long)=8, sizeof(long long)=8, sizeof(size_t)=8
foo<int>
foo<long>
foo<long long>
foo<size_t>
foo<long>
foo<T> with T=a
foo<T> with T=s
foo<int>
foo<long long>
foo<T> with T=j
foo<T> with T=y
So here is what I do not understand:
- If
longand long longis the same type, why does the compiler allow both specializations to coexist? - Why is adding specialization to
int64_tcause an error? - Why
foo<int64_t>is it permitted how foo<long long>and not foo<long>? - Why
foo<ssize_t>is it permitted how foo<long>and not foo<long long>? foo<uint64_t> foo<size_t>?- , , ? , ?