How does pattern specialization work with integer types?

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:

// clang test.cc -std=c++11 -lc++
#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"; }
// template <> void foo<int64_t>()  { std::cout << "  foo<int64_t>\n"; } // error


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>?
  • , , ? , ?
+6
2

1) long long long - , ?

long long long , .

2) int64_t ?

std::int64_t , ( typedef using)

3) foo<int64_t> foo<long long>, foo<long>?

std::int64_t long long, long ( ...); std::int64_t long long;

4) foo<ssize_t> foo<long>, foo<long long>?

, std::int64_t: ssize_t ( ) ( ) long, long long

5) foo<uint64_t> foo<size_t>?

std::uint64_t std::size_t , (unsigned long unsigned long long, ),

6) , , ? , ?

(1) ( , long long long ), .

, , , std::is_same .

+4

c++ , , . , char unsigned char, signed char, . long long long , . , struct A{}; struct B{}; , .

, , , typedef using .

  • long long long - , ?

long long long , .

  1. int64_t ?

typedef . int64_t typedef long int long long int. , . , int64_t .

  1. foo<int64_t> foo<long long>, foo<long>?
  2. foo<ssize_t> foo<long>, foo<long long>?

. , .

  1. foo<uint64_t> foo<size_t>?

, uint64_t size_t . , .

  1. , , ? , ?

, , . , , , . int, , int. , , , .

, - , , std::numeric_limits <type_traits> , .

+3

All Articles