Results 1 to 17 of 17

Thread: Qt initializer

  1. #1
    Join Date
    Sep 2011
    Posts
    8
    Qt products
    Qt4

    Default Qt initializer

    I need one line to initialize a QList

    This does not work,

    Qt Code:
    1. const QList<int> & test(QList<int>() << 7 << 9); //I know, I could simply write const QList<int> test(...); without using & since QList does copy only on write...but....
    To copy to clipboard, switch view to plain text mode 

    My reference points to an empty QList. Why? I thought it is equivalent to this:

    Qt Code:
    1. QList tmp;
    2. tmp << 7;
    3. tmp << 9;
    4. const QList<int> & test(tmp); //this *is* ok
    To copy to clipboard, switch view to plain text mode 


    And note that assuming there is a function fn somewhere,

    Qt Code:
    1. int fn(const QList<int> & list) {return list.size();}
    2.  
    3. fn(QList<int>() << 7 << 9); //works!! isn't it the same?
    To copy to clipboard, switch view to plain text mode 

    Thanks,
    J
    Last edited by j4l; 20th September 2011 at 11:27.

  2. #2
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Qt initializer

    Reference is just like a pointer, it needs a valid, existing object to point to. In your case (1) the temporary list gets deleted soon after its created, reference does not "copy" the content of temporary objects. Second case is ok, reference points to an existing object.
    Why do you want to use references anyway ?
    ---
    edit:
    int fn(const QList<int> & list) {return list.size();}

    fn(QList<int>() << 7 << 9); //works!! isn't it the same?
    The argument passed to function remains valid until the function returns, note that you cannot use the passed argument after the fn() finishes, because it no longer exists. In your first code snippet the argument passed to reference initializer gets deleted too, but you still want to use it later ( by holding a reference to it ).
    Last edited by stampede; 20th September 2011 at 11:11.

  3. #3
    Join Date
    Sep 2011
    Posts
    8
    Qt products
    Qt4

    Default Re: Qt initializer

    Hi stampede,

    Thanks for the answer but I think you are wrong. C++ Standard does allow to keep references to temporaries. A temporary is kept alive as long as there is a reference in scope. E.g, try this

    Qt Code:
    1. std::vector<int> someFunction()
    2. {
    3. std::vector<int> v;
    4. v.push_back(6);
    5. return v;
    6. }
    7.  
    8. const std::vector<int> & v = someFunction(); //perfectly valid, temporary is returned and kept alive (const & can always bind to temporaries)
    To copy to clipboard, switch view to plain text mode 

    I do this for performance reasons; since returned data is const, why make a copy?

  4. #4
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Qt initializer

    QList uses copy-on-write semantics, so no copy is made when you assign one list to another. Actual copy is made only when you change one of the objects.

  5. #5
    Join Date
    Sep 2011
    Posts
    8
    Qt products
    Qt4

    Default Re: Qt initializer

    I know that with QList, that reference is redundant. That's just a habit I got with non-qt code.

    Still, to me it seems that the initializer example should work the same way as the function call. I'm still confused.

    Thanks,

  6. #6
    Join Date
    Nov 2010
    Posts
    315
    Thanked 53 Times in 51 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Qt initializer

    Men, doesn't your compiler complain (give warnings) that something is wrong? I'm pretty sure it does!
    It looks like that you are confusing C++ references with reference types form Java or C#.
    This two things are completely different and in C++ temporary automatic objects are allays ceases to exist in next line.
    In last example someFunction() returns a value, compiler optimizes that by delivering to this function pointer where result should be created. In you use case of someFunction() first creates temporary object and reference to that is stored (so it is wrong). You are just lucky that it works. If you do something more with this reference you will have a crush.

  7. #7
    Join Date
    Sep 2011
    Posts
    8
    Qt products
    Qt4

    Default Re: Qt initializer

    nope,

    const T & x = T(); //is perfectly valid code in c++

    creates a temporary T by calling ctor: T()

    then keeps it alive in local scope (where const T & x is defined)


    Try it with any C++ (not java) compiler

    See http://herbsutter.com/2008/01/01/got...portant-const/
    Last edited by j4l; 20th September 2011 at 12:38.

  8. #8
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Qt initializer

    You are right, but I think those two examples are slightly different. What I meant was that in cases as below:
    Qt Code:
    1. // (1)
    2. const QList<int> & x = (QList<int>() << 2);
    3. const QList<int> & x2(QList<int>() << 1);
    To copy to clipboard, switch view to plain text mode 
    the temporary lists are deleted before the declared reference can "catch" them, but here:
    Qt Code:
    1. const QList<int>& x = someMethodReturningQListByValue();
    To copy to clipboard, switch view to plain text mode 
    the list is kept "alive" until reference goes out of scope, because its returned by value. Same as constructor T(). Try to return the reference (const or not, no matter), compiler will start to complain.
    Remember that operators from (1) returns a reference ( are declared as QList<T>& operator<< )
    If you create custom operator << and return the List by value, all will work.

  9. #9
    Join Date
    Oct 2010
    Location
    Berlin, Germany
    Posts
    358
    Thanks
    18
    Thanked 68 Times in 66 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Qt initializer

    AFAIK does the scope of a parameter list ends when the called function returns. So, in your case, the list is valid during the copy constructor, but it gets invalid when the constructor returns.

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Qt initializer

    What is the actual error you are getting when compiling with g++?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  11. #11
    Join Date
    Sep 2011
    Posts
    8
    Qt products
    Qt4

    Default Re: Qt initializer

    I get no compile error.
    It's just that I get a call of the QList dtor and the list I am referencing is empty, as if the two appends (<<) were never performed.
    Tried on msvc and gcc as well

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Qt initializer

    So apparently you are wrong with the thing related to persisting references to temporary objects. From what I understand you need to assign the reference to an object for this to work. The temporary object will persist through its scope but then it has to be copied to something that exists.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  13. #13
    Join Date
    Sep 2011
    Posts
    8
    Qt products
    Qt4

    Default Re: Qt initializer

    I was wrong assuming that the expression QList() << 7 << 9 returns a temporary.
    Yes, QList() creates a temporary, then is gets 7 and 9 appended, which each time a value is appended by calling <<, this call returns QList& which is not a temporary object but a reference to a temporary.
    (because QList:perator << return QList&). Note that returned QList& is not a temporary anymore, but a lvalue itself.

    Conclusion

    1) QList<int> & l1 = QList<int>(); //illegal c++, rvalue (temporary) may only be bound to const&; compilers are smart and warn about this!

    2) const QList<int> & l2 = QList<int>(); //perfectly valid, legal c++, const& binds to directly to the temporary/rvalue (list ctor called; no dtor called)

    3) QList<int> & l3 = QList<int>() << 7 << 9; //non const reference is dangerously!! bound to the result of the expression QList() << 7 << 9, a reference! to a temporary itself, and temporary is destroyed immediately (dtor is called and I get a dangling reference)

    4) const QList<int> & l4 = QList<int>() << 7 << 9; //I was hoping to get const reference bound to the temporary, therefore to keep temporary alive; but in this case, const is useless, bounds to a ref to a temporary and temporary gets destroyed, same as in 3); dtor is called, I get a dangling reference


    While 2) is a great option in c++ and 1) is discarded by the compiler, 3) and 4) are similarly dangerous and unfortunately silent. I learned something :-)

    Thank you all

  14. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Qt initializer

    To be honest in this particular case there is no point in using a const reference, you can use a copy-constructor which is usually very cheap.

    Qt Code:
    1. QList<int> l1 = QList<int>() << 1 << 2;
    To copy to clipboard, switch view to plain text mode 

    I think C++0x has some additional optimizations here and it will detect the list gets destroyed after assignment and it will just "move" the data from the temporary list to the l1 object. Or at least the developer of the class will be able to declare such behaviour.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  15. #15
    Join Date
    Sep 2011
    Posts
    8
    Qt products
    Qt4

    Default Re: Qt initializer

    yes, I know, QList and other qt containers are using copy on write, so this does not really make sense for QList.

    But actually I was worried about the idiom itself, and less about QList.

    Indeed, c++11 will bring rvalue references as well, but it seems I still have to learn about c++03 in the mean time, at least about subtle things like these.

  16. #16
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Qt initializer

    Quote Originally Posted by j4l View Post
    yes, I know, QList and other qt containers are using copy on write, so this does not really make sense for QList.

    But actually I was worried about the idiom itself, and less about QList.
    Actually I meant a general case, not implicitly-shared classes.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  17. #17
    Join Date
    Sep 2011
    Posts
    8
    Qt products
    Qt4

    Default Re: Qt initializer

    in the general case, I am avoiding a copy (I wanted a single line of code)

Similar Threads

  1. Replies: 1
    Last Post: 4th September 2008, 14:55
  2. expected initializer before »)« token
    By Holy in forum Qt Programming
    Replies: 2
    Last Post: 24th May 2008, 16:24

Tags for this Thread

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.