Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] Signal parameter of type std::unique_ptr
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] Signal parameter of type std::unique_ptr

Scheduled Pinned Locked Moved General and Desktop
7 Posts 2 Posters 11.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    rincewind
    wrote on 2 Oct 2013, 16:25 last edited by
    #1

    Is it possible to use a std::unique_ptr in a signal? I'm trying to embrace the new language features of C++11 and have been using unique_ptr and shared_ptr where possible.

    Now I want to emit a signal of the form:
    @void newThing(std::unique_ptr<Thing> thing);@

    When I emit the signal, I do it like this:
    @auto newThing = std::unique_ptr<Thing>(new Thing());
    ...
    emit newThing(std::move(newThing));@

    I get compiler errors in the moc file, so I'm wondering if I'm on a wild goose chase here that Qt 4.8.5 at least doesn't support this.

    1 Reply Last reply
    1
    • T Offline
      T Offline
      t3685
      wrote on 2 Oct 2013, 17:16 last edited by
      #2

      You need to register the type so that moc knows what it is.

      http://qt-project.org/doc/qt-4.8/custom-types.html

      So in your case you need to declare

      @Q_DECLARE_METATYPE(std::unique_ptr<Thing>);@

      in a header file and call @qRegisterMetaType<std::unique_ptr<Thing>>();@ before your signal and slots are used.

      By the way, Qt 4.8.5 is compiled with GCC 4.4 which does not support all C++11 features just so you know (unless you compiled Qt yourself of course :))

      1 Reply Last reply
      0
      • R Offline
        R Offline
        rincewind
        wrote on 2 Oct 2013, 17:35 last edited by
        #3

        Thanks t3685!

        I've seen references to Q_DECLARE_METATYPE but I understood it to only be required when using a queued connection. Thanks for pointing me in the right direction.

        I have to support Windows and Linux and have been developing on Linux so far. I discovered that I couldn't compile my code using C++ features on Windows because the Qt SDK installed GCC 4.4, so I downloaded the latest MinGW Builds build which includes GCC 4.8.1. I rebuild Qt with this compiler. On Ubuntu 12.10 I'm using GCC 4.7 and I assume the Qt library was built with that version as well...

        Thanks for the help!

        1 Reply Last reply
        0
        • R Offline
          R Offline
          rincewind
          wrote on 2 Oct 2013, 18:38 last edited by
          #4

          Now I get the same error on the Q_DECLARE_METATYPE line:
          @/usr/include/qt4/QtCore/qmetatype.h:142: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&)@

          I can't see how the meta type registration will have any influence, as I understand it is needed when transferring the parameter in a QVariant.

          Going back to the emit of the signal...

          The qt_static_metacall() method contains the following case:
          @case 1: _t->newThing((reinterpret_cast< std::unique_ptr<Thing>()>(_a[1]))@

          I suppose the problem is that the std::move is not used in the generated method call.

          1 Reply Last reply
          0
          • R Offline
            R Offline
            rincewind
            wrote on 3 Oct 2013, 10:55 last edited by
            #5

            I've changed the parameter to std::shared_ptr, which works. At least I can make the code work, but I would still like too be able to use unique_ptr when it is the most appropriate smart pointer for the circumstance. So, I'm keeping it open.

            1 Reply Last reply
            0
            • T Offline
              T Offline
              t3685
              wrote on 3 Oct 2013, 16:24 last edited by
              #6

              From the documentation:

              "Creating a Custom Type Before we begin, we need to ensure that the custom type we are creating meets all the requirements imposed by QMetaType. In other words, it must provide:

              a public default constructor,
              a public copy constructor, and
              a public destructor."
              

              So your custom type (in this case std::unique_ptr) needs to meet those requirements. However, as you can see from your error that the copy constructor was "deleted" (google the C++11 keyword delete in header files).

              Which is logical if you think about it in hindsight :), when a signal is emitted, multiple slots can be connected to it: how can multiple slots have the same std::unique_ptr? I probably should have realized this before I pointed you to the documentation (my bad!).

              std::shared_ptr works because well, it can be shared :).

              1 Reply Last reply
              1
              • R Offline
                R Offline
                rincewind
                wrote on 4 Oct 2013, 05:58 last edited by
                #7

                I missed the simple issue of sending the unique_ptr to multiple destinations completely! In my case I was thinking of the single slot provider and didn't think of the implications of having multiple slots breaking the unique_ptr contract! Hey, that's how you learn...

                Thanks!

                1 Reply Last reply
                0

                1/7

                2 Oct 2013, 16:25

                • Login

                • Login or register to search.
                1 out of 7
                • First post
                  1/7
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved