Calculating array size in C++ This code shows two ways to calculate size of array of any type. I would like to know, which should be preferred? Is there any advantage/disadvantage?

#include &lt;iostream&gt;

// First method
template&lt;typename Arr&gt;
std::size_t array_size_1(const Arr&amp; arr)
{
  return sizeof(arr)/sizeof(arr[0]);
}
// Second method
template&lt;typename T, std::size_t sz&gt;
std::size_t array_size_2(const T (&amp;arr)[sz])
{
  return sz;
}

int main() {
  int arr[] = {1,2,3,4,5};
  std::string sarr[] = {"abc", "def", "ghj"};
  std::cout &lt;&lt; array_size_1(arr) &lt;&lt; "\n";
  std::cout &lt;&lt; array_size_2(sarr) &lt;&lt; "\n";
  return 0;
}
Both suffer (equal amounts) from the problem that when you call them, the compiler has to go instantiate a new function from the template. The code all ends up inlined after optimization, but it does make more work for the compiler than something like

#define NELEM(x) (sizeof(x) / sizeof (x)[0])


The benefit of array_size_2 is that if you try to call it as

int *p = nullptr;
std::vector&lt;int&gt; v;
size_t a = array_size_2(p);  // ERROR
size_t b = array_size_2(v);  // ERROR


the compiler will reject the call as ill-formed. Whereas if you do the same thing with array_size_1 or NELEM, you'll just get for example sizeof(int*) / sizeof(int) or sizeof(vector&lt;int&gt;) / sizeof(int), which isn't meaningful.

So array_size_2 saves you from accidentally writing something meaningless. Especially in cases like

int foo(int a[]) {
    return array_size_1(a);  // OOPS!
}


where int a[] is just syntactic sugar for int *a and there's no actual array in existence at all.