Results 1 to 7 of 7

Thread: C++, templates and arrays of pointers

  1. #1
    Join Date
    Oct 2009
    Beans
    83

    C++, templates and arrays of pointers

    Hi,

    I have a small header where I defined some functions to manage dynamic arrays I need. One of these functions is:

    Code:
    /*!
        This subroutine increases the size of a dynamic array by 1 and writes data at such location, effectively
        implementing an append instruction.
        @params:
        Target:        IN        current array
        Array_Size:    IN        size of the current array
        Appendee:    IN        data to append to the array
    
        @return:            pointer to the extended array
    */
    template <typename ArrayType, typename SizeType>
    inline ArrayType* Array_Append (ArrayType* Target, SizeType& Array_Size, ArrayType& Appendee)
    {
        ArrayType* tmp;
        tmp = new ArrayType [Array_Size + 1];
        memcpy (tmp, Target, Array_Size * sizeof (ArrayType));
    
        delete [] Target;
    
        tmp [Array_Size] = Appendee;
        Array_Size++;
    
        return tmp;
    }
    As it happens, it turns out that I am mostly using this with ArrayType = StructuredType*, where StructuredType is a structure. I.e.

    Code:
    struct TT
    {int a;}
    In the code something like this happens:

    Code:
    TT** Array (NULL);
    
    int Elements (0);
    
    Array = new TT* [1];
    ++Elements;
    
    TT* AppendOneOfThese = new TT [10];
    
    // I want to append a pointer to the 4th element of AppendOneOfThese in Array
    Array_Append (Array, Elements, &AppendOneOfThese [3]);
    The compiler gives me the following error:
    Code:
    error: no matching function for call to ‘Array_Append(TT**&, unsigned int&, TT*)’
    note: candidates are: ArrayType* Array_Append(ArrayType*, SizeType&, ArrayType&) [with ArrayType = TT*, SizeType = unsigned int]
    Actually, it only gives me this error on one line, in a new function. The 7 other times I use it on different types and different functions it gives me no problem (although I remember seeing this error on those too the first time I was debugging them).
    So, I smell some error by my part... is Array_Append ok? Why does it searches for a function where its first parameter is TT**& instead of TT**?
    Last edited by Dirich; June 15th, 2013 at 09:37 AM.

  2. #2
    Join Date
    Jul 2008
    Location
    England
    Beans
    866

    Re: C++, templates and arrays of pointers

    I think you are looking for
    Array_Append<TT*>(YOUR ARGS);
    So that you are specifying the type for your template.
    Paul

  3. #3
    Join Date
    Oct 2009
    Beans
    83

    Re: C++, templates and arrays of pointers

    First of all, thanks for the help.
    Although you are right in saying I'm not specifying the template argument, the compiler deduces it correctly itself, so the problem is not that.
    Proof is the second line (the "note" one) or the fact that it works perfectly on the other 7 instances I mentioned.
    Anyway, once I followed your suggestion, the compiler gave the same output (without the hypotesis on the type, since now I've specified it, of course):

    Code:
    error: no matching function for call to ‘Array_Append(TT**&, unsigned int&, TT*)’
    Once again, it adds an & after TT**.


    UPDATE:
    There is a difference between the two cases, the one in which everything works and the one when I get the error. In the first case the Appendee is a pointer to a dynamic struct, the other time it is a pointer to struct in a dynamic array (&otherArray [item_number]). But in the end they are both pointers to a certain kind of struct, the fact that one is standalone and the other is in a collection (array) should not matter. Also, this is the 3rd field, the compiler is making funny stuff with the first one.
    Or so I thought...

    This does not spawn the error:
    Code:
    TT** Array (NULL);
    int Elements (0);
    
    Array = new TT* [1];
    ++Elements;
    
    TT* AppendThis = new TT;
    
    Array_Append (Array, Elements, AppendThis);
    This does spawn the error

    Code:
    TT** Array (NULL);
    int Elements (0);
    
    Array = new TT* [1];
    ++Elements;
    
    TT* AppendOneOfThese = new TT [10];
    
    // I want to append a pointer to the 4th element of AppendOneOfThese in Array
    Array_Append (Array, Elements, &AppendOneOfThese [3]);
    I need to make it work in the second case, any idea? I still do not get why the error complains as he does.


    UPDATE2:
    Found a solution switching from:
    Code:
    template <typename ArrayType, typename SizeType>
    
    inline ArrayType* Array_Append (ArrayType* Target, SizeType& Array_Size, ArrayType& Appendee)
    to

    Code:
    template <typename ArrayType, typename SizeType>
    
    inline ArrayType* Array_Append (ArrayType* Target, SizeType& Array_Size, ArrayType Appendee)
    But it is still not clear to me the behavior of the compiler, and I would very much appreciate an explaination, if someone knows the reason of it.
    Last edited by Dirich; June 14th, 2013 at 09:13 PM.

  4. #4
    Join Date
    Apr 2005
    Location
    Hampshire, UK
    Beans
    1,274

    Re: C++, templates and arrays of pointers

    "&AppendOneOfThese [3]" is a temporary, and temporaries cannot be bound to non-const references.

    This works:

    Code:
    #include <iostream>
    #include <cstring>
    /*!
        This subroutine increases the size of a dynamic array by 1 and writes data at such location, effectively
        implementing an append instruction.
        @params:
        Target:        IN        current array
        Array_Size:    IN        size of the current array
        Appendee:    IN        data to append to the array
    
        @return:            pointer to the extended array
    */
    template <typename ArrayType, typename SizeType>
    inline ArrayType* Array_Append (ArrayType* Target, SizeType& Array_Size, const ArrayType& Appendee)
    {
        ArrayType* tmp;
        tmp = new ArrayType [Array_Size + 1];
        memcpy (tmp, Target, Array_Size * sizeof (ArrayType));
    
        delete [] Target;
    
        tmp [Array_Size] = Appendee;
        Array_Size++;
    
        return tmp;
    }
    
    struct TT
    {int a;};
    
    int main()
    {
        TT** Array (NULL);
    
        int Elements (0);
    
        Array = new TT* [1];
        ++Elements;
    
        TT* AppendOneOfThese = new TT [10];
    
        // I want to append a pointer to the 4th element of AppendOneOfThese in Array
        TT* blah = &AppendOneOfThese[3];
        Array_Append (Array, Elements, AppendOneOfThese + 3);
    }

  5. #5
    Join Date
    Oct 2009
    Beans
    83

    Re: C++, templates and arrays of pointers

    Thanks Zod, I tried both solutions. The arithmetic of pointers failed to provided a non-temporary object, but the instantiation of blah worked perfectly!
    It is indeed the temporary and referement problem that is detected, although I'd say it's a clumsy output the compiler provides me!

  6. #6
    Join Date
    Apr 2005
    Location
    Hampshire, UK
    Beans
    1,274

    Re: C++, templates and arrays of pointers

    Quote Originally Posted by Dirich View Post
    Thanks Zod, I tried both solutions. The arithmetic of pointers failed to provided a non-temporary object, but the instantiation of blah worked perfectly!
    It is indeed the temporary and referement problem that is detected, although I'd say it's a clumsy output the compiler provides me!
    No problem clang's output is slightly better, but still doesn't quite get to the nub of the matter. Might file a bug report ...

  7. #7
    Join Date
    Jun 2007
    Location
    Maryland, US
    Beans
    6,273
    Distro
    Kubuntu

    Re: C++, templates and arrays of pointers

    @ Dirich

    I'm glad you solved the problem with your program.

    As I was looking through your code, I must say I found it difficult (not impossible) to determine which text was a variable (object) type and which was the variable itself.

    I've been developing s/w in C++ for over 15 years (in a professional setting), and it is customary in C++ to define object using an uppercase letter for the first character in a word (name), and for variables to start with lowercase. For example:
    Code:
    Array myArray;
    
    MyObject object;
    Also, why are you managing an array of data? Why not just use the STL vector? Are you precluded from using STL because of some restriction? If you can't use STL, then perhaps modeling your own vector class should be something you could focus on.

    In conclusion, if you are developing s/w for your own gratification, then my advice should not matter much to you. However, if you plan on having others peer review your work (and posting on this forum seems like you do), then it would be helpful if you would assist them in being able to read your code in an efficient manner.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •