Array size Template and references to array

Discussion in 'C++' started by amparikh@gmail.com, Aug 3, 2005.

  1. Guest

    Hi all,
    I was just browsing the archives when I saw one fo the messages posted
    recently about array size template et al.

    All along, I have been using the usual template to get the size of the
    array.
    template<typename T, std::size_t N>
    std::size_t size_of(T(&)[N])
    {
    return N;
    }

    But as one person pointed out, the following definition fails with the
    above template, which is what I have always noticed when I use similar
    definitions.
    int x[5];
    int y[size_of(x)]; //fails here

    I always went back to the simple way in these definition
    int y[sizeof(x)/sizeof(*x)]; //the simple way.

    The person who pointed out the error, also had the template that
    works.I would like to use this template all the time, but I am not
    quite sure, what it is exactly doing. It is trying to get a reference
    to an array and then get the size of that array(which itself is a
    reference to a char)..Not quite sure. Can somebody explain ?

    template <typename T, unsigned N>
    char ( & NelemArrayFunc( T ( & )[ N ] ) )[ N ];

    #define Nelem( A ) (sizeof( NelemArrayFunc( A ) ))

    Thanks.
    , Aug 3, 2005
    #1
    1. Advertising

  2. __PPS__ Guest

    I also didn't know that it was possible to do like this.
    int x[5];
    int y[size_of(x)]; //fails here
    for me it works with g++, but doesn't with ms vc71;
    .....
    basicly
    template <typename T, unsigned N>
    char ( & NelemArrayFunc( T ( & )[ N ] ) )[ N ];

    means declaration of a function that takes a reference to array of N
    T's (T[N]) and returns a reference to array of N chars. (references are
    used to preseve type info)

    and then macro
    #define Nelem( A ) (sizeof( NelemArrayFunc( A ) ))
    uses sizeof NelemArrayFunc( A ); where NelemArrayFunc is only valid for
    arrays. When this function used as an argument to sizeof the only
    information used is the function's return type, that is for T[N] it
    returns char[N], and sizeof(char[N]) is N



    NelemArrayFunc could be written also like this:
    template <typename T, unsigned N>
    char ( & NelemArrayFunc( T ( & )[ N ] ) )[ N ]{
    char x[N];
    return x;
    }


    Between, anyone has a good link for info on declaration of functions
    (as for such unusual declaration) and also declaration of pointers to
    such functions. For example, how would I need to declare pointer to
    NelemArrayFunc???

    thanks
    __PPS__, Aug 4, 2005
    #2
    1. Advertising

  3. benben Guest

    I think the problem is that when you pass a raw array T arr[N] to a
    function as an argument the array "degrades" to a pointer T* arr. Therefore
    part of the type information (N) is lost. This, however, is not the case
    with type passed to class templates. And therefore with some odd looking
    code we can implement size_of this way:

    template <typename T, int N>
    class size_calc;

    template <typename T, int N>
    class size_calc<T[N]>
    {
    public:
    enum {size = N};
    };

    template <typename T>
    int size_of(const T& t)
    {
    return size_calc<T>::size;
    }

    Notice the declaration of size_of hides the fact that t is an array from the
    compiler, and hence prevents the type degrading.
    benben, Aug 4, 2005
    #3
  4. benben Guest

    My previous post is completely stupid. Forget it.

    Here is what I should have posted:

    template <typename T, int N>
    int size_of (const T (&arr) [N])
    {
    return N;
    }
    benben, Aug 4, 2005
    #4
  5. __PPS__ wrote:
    ....
    >
    >
    > Between, anyone has a good link for info on declaration of functions
    > (as for such unusual declaration) and also declaration of pointers to
    > such functions. For example, how would I need to declare pointer to
    > NelemArrayFunc???


    template <typename T, unsigned N>
    char ( & NelemArrayFunc( T ( & )[ N ] ) )[ N ];

    char ( & (* XNelemArrayFunc)( int ( & )[ 3 ] ) )[ 3 ];

    XNelemArrayFunc = & NelemArrayFunc<int, 3>;
    Gianni Mariani, Aug 6, 2005
    #5
  6. benben wrote:
    > I think the problem is that when you pass a raw array T arr[N] to a
    > function as an argument the array "degrades" to a pointer T* arr. Therefore
    > part of the type information (N) is lost. This, however, is not the case
    > with type passed to class templates. And therefore with some odd looking
    > code we can implement size_of this way:
    >
    > template <typename T, int N>
    > class size_calc;
    >
    > template <typename T, int N>
    > class size_calc<T[N]>
    > {
    > public:
    > enum {size = N};
    > };
    >
    > template <typename T>
    > int size_of(const T& t)
    > {
    > return size_calc<T>::size;
    > }
    >
    > Notice the declaration of size_of hides the fact that t is an array from the
    > compiler, and hence prevents the type degrading.


    return is a run-time expression. sizeof is a compile-time expression so
    it can be used wherever a constant is needed.
    Gianni Mariani, Aug 6, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roger Leigh
    Replies:
    8
    Views:
    418
    Karl Heinz Buchegger
    Nov 17, 2003
  2. Replies:
    3
    Views:
    437
    Victor Bazarov
    Nov 10, 2004
  3. Jonathan Bartlett
    Replies:
    3
    Views:
    428
  4. DanielEKFA
    Replies:
    8
    Views:
    590
    DanielEKFA
    May 16, 2005
  5. Jason Cavett

    Preferred Size, Minimum Size, Size

    Jason Cavett, May 23, 2008, in forum: Java
    Replies:
    5
    Views:
    12,530
    Michael Jung
    May 25, 2008
Loading...

Share This Page