How does this Array Size Template Work?

前端 未结 3 1735
臣服心动
臣服心动 2020-12-10 02:41

I came across this snippet

template   
char (&ArraySizeHelper(T (&array)[N]))[N];  
#define arraysize(array) (sizeof(Arra         


        
相关标签:
3条回答
  • 2020-12-10 03:04

    This blog on MSDN precisely describes how it works. Very interesting story. Take a look at it.

    0 讨论(0)
  • 2020-12-10 03:14

    The function template is named ArraySizeHelper, for a function that takes one argument, a reference to a T [N], and returns a reference to a char [N].

    The macro passes your object (let's say it's X obj[M]) as the argument. The compiler infers that T == X and N == M. So it declares a function with a return type of char (&)[M]. The macro then wraps this return value with sizeof, so it's really doing sizeof(char [M]), which is M.

    If you give it a non-array type (e.g. a T *), then the template parameter inference will fail.

    As @Alf points out below, the advantage of this hybrid template-macro system over the alternative template-only approach is that this gives you a compile-time constant.

    0 讨论(0)
  • 2020-12-10 03:19

    This isn't the nicest way of doing it, but since you're asking: The return type of the template function ArraySizeHelper is char[N], where the argument of the function is a (reference to an) array of size N of type T. Template argument deduction instantiates this template with the matching number N, and so sizeof(char[N]) is just N, which is what you get.

    A nicer version could be written as follows. (You need C++0x for constexpr; if you omit it, this will not be a constant expression.)

    template <typename T, size_t N> constexpr size_t array_size(const T (&)[N]) { return N; }
    

    Usage:

    int x[20];
    array_size(x); // == 20
    

    Update: If you are in C++0x, here is another solution that gives a constexpr, thanks to decltype:

    #include <type_traits>
    
    template <typename T> struct array_traits;
    template <typename T, unsigned int N> struct array_traits<T[N]>
    {
       static const unsigned int size = N;
       typedef std::decay<T>::type type;
    };
    
    // Usage:
    int x[20];
    array_traits<decltype(x)>::size; // == 20
    
    0 讨论(0)
提交回复
热议问题