How to return array from a function in QT



  • Hello,

    I want to return an array from a function using QT but i can not do it for some reason. I used to do it by ref, passing &array[0] to the function in C++ but it seems i need to use qpointer

    is this correct?

    ex:
    @
    int x=1;
    QPointer <int> op;
    test(x,op);

    void test(int ip, QPointer <int> op)
    {
    for (int i=0; i<=10; i++)
    {
    op.append(i*ip);
    }

    }

    @



  • You should be able to do it the same way. I know some compilers have issues with member template functions but this is going back a while.

    @
    int x=1;
    QPointer<int> op;
    test(x,op);

    void test(int ip, QPointer<int> &op)
    {
    for (int i=0; i<=10; i++)
    {
       op.append(i*ip);
    }
     
    }
    

    @

    Maybe something like this to make it easier on the eyes

    @
    typedef QPointer<int> QPointerInt;

    int x=1;
    QPointerInt op;
    test(x,op);
     
    void test(int ip, QPointerInt &op)
    {
    for (int i=0; i<=10; i++)
    {
       op.append(i*ip);
    }
     
    }
    

    @

    What error is returned from the compiler (or linker)?



  • Do you want to do something like this?:

    @
    int x = 1;
    std::vector<int> arr = test(x);

    std::vector<int> test(int ip)
    {
    std::vector<int> rv;
    for (int i = 0; i <= 10; ++i)
    {
    rv.append(i ( ip);
    }
    return rv;
    }
    @

    The compiler is usually so clever to use return value optimization (RVO) so that only one vector gets created and no copies are made here.

    Peer



  • i wanted to return an array of data (int for ex) through a void function by ref ..
    Method 1: did not work,i can not do something like op[1]++ in the function
    Method 2: is nice but is not a void fn

    Sherif



  • Well, then you need to write something like this:

    @
    int x = 1;
    std::vector<int> arr;
    test(x, arr);

    void test(int ip, std::vector<int> &arr)
    {
    for (int i = 0; i <= 10; ++i)
    {
    arr.push_back(i * ip);
    }
    }
    @

    A alternative is to use a pointer, however I would encourage you to use the reference approach if the array definitely exists:

    @
    int x = 1;
    std::vector<int> arr;
    test(x, &arr);

    void test(int ip, std::vector<int> *pArr)
    {
    if (pArr)
    {
    for (int i = 0; i <= 10; ++i)
    {
    pArr->push_back(i * ip);
    }
    }
    else
    {
    // If necessary handle an empty pArr pointer.
    }
    }
    @

    Of course you can use QVector or any other container for one of these approaches.



  • thank you i used this approach, but could you please help me to understand it?
    why did you use &arr in the function declaration? Since we have an array so we assume to send the first pointer address with & in test(x,&arr[0]) according to my understanding and not in the declaration ..

    @
    int x = 1;
    std::vector<int> arr;
    test(x, arr);
    void test(int ip, std::vector<int> &arr)
    {
    for (int i = 0; i <= 10; ++i)
    {
    arr.push_back(i * ip);
    }
    }
    @



  • In Qt all container classes are implicitly shared, so in regular C++ and the std library prior to move semantics there was the danger of creating an unnecessary copy. That is not the case of Qt containers, you can pass containers as parameters or return them from functions without having to worry that a deep copy may occur. A copy will automatically be made if you try to modify the information. No need to use pointers or references or whatever.



  • :SherifOmran

    When we write
    @
    void test(int ip, std::vector<int> &arr)
    @

    we copy a reference to the whole array into the function test, not a pointer. It does not matter that we have an array here, we have an object and we want to use exactly this object inside the test function. Look up how to work with references to fully understand what we are doing here. ("C++ References":http://www.cprogramming.com/tutorial/references.html)

    :utcenter

    The implicit sharing of Qt container classes would not help here as the original array shall be modified by test, not a copy of it. Using an implicit shared container would cause a deep copy the moment the first push_back happens. From that moment on there would be two arrays and the second one inside test would cease to exist when the end of test is reached, the first one would still be empty. The call of the test function would then be in vain.



  • PeerS - a reference and a pointer are pretty much the same thing, it is just a memory address. The difference is there is no pointer arithmetic with the reference, it can't be reassigned and it is automatically dereferenced. There is no such thing as a "reference to the whole array" - it is just the memory address of the array's location. It is irrelevant whether you pass by a pointer or by reference, the latter is just more clean and convenient.

    And BTW the title says "how to return array from a function" - in this context you can create your container inside the function and just return it taking advantage of implicit sharing and returning a shallow copy. A pre-existing container should not be returned but passes by reference like many of the examples already show.



  • A pointer and a reference to an object are technically very similar, yes. Semantically, however, they are quite different. Semantically a pointer represents the address of the object in memory while the reference represents the object itself. This is why you can do arithmetic with a pointer, it just represents a memory location and pointer arithmetic changes the memory location it points to. The pointer also can be a nullptr meaning it currently does not point to any memory location. In contrast the reference represents the object itself. No need to dereference like when using a pointer, no possibility to reassign this reference, it represents a specific object.

    This difference in the semantics of pointer and reference is what I see as most important when it comes to decide whether to use a reference or a pointer. I use a reference whenever it shall be an alias to an existing object. I use a pointer if either I need to do arithmetic with it or if the object not necessarily has to exist, so if the pointer can be a nullptr.

    With reference to the whole array I wanted to emphasize that it represents the whole array in contrast to a pointer to the first element as the OP mentioned in one of its post.

    Yes, if you you create the container inside the function, then simply return it. There is even no copy cost because there is no copy at all. Modern compilers optimize away any copy in this situation, they do return value optimization.



  • A reference refers to the memory address of the object, just like the pointer does. They are also the same size. I think even the & operator used on a reference to an object will return the same value a pointer to that object will return, e.g. the memory address. In fact, you can see C people passing by pointer refer to that as passing by reference, since there are no references in C. I myself never found it particularly beneficial to think of references as more than constant pointers to objects which are automatically dereferenced.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.