16

I tried to do this :

connect(this, SIGNAL(signalClicked(int&)),  classA, SLOT(doWork(int&)));

But I get the message in the title. So I've explored the internet and I came up with this solution which is not working either:

 qRegisterMetaType<int&>("Type");
 connect(this, SIGNAL(signalClicked(Type)),  classA, SLOT(doWork(Type)));

Error: no matching function for call to ‘qRegisterMetaType(const char[5])’

Any solutions?

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
Thibel
  • 277
  • 1
  • 5
  • 13

1 Answers1

29

If Qt is trying to queue the arguments that means that the connection is between threads. This will not work for non-const references.

You could use a reference_wrapper to work around this, but I would strongly suggest that you reconsider your design. Passing values by reference in signal/slot connections is not a good idea.

Dan Milburn
  • 5,600
  • 1
  • 25
  • 18
  • I know it is not the good way to do it but I am new to this and that is the only solution I found. Actually what I'm trying to achieve is to update an attribute in the main thread and read it from another thread in an infinite loop. I'll try what you've suggested though – Thibel Jun 13 '13 at 09:42
  • 4
    @Dan-Milburn, as Qt copies the object, why is not a good idea to pass values by reference? – TheDarkKnight Jun 13 '13 at 09:47
  • 1
    If Qt takes a copy, what is the point in passing by (non-const) reference? The receiving slot would not be able to modify the original anyway (while being mislead into thinking that it could). Further, the point behind Qt signals/slots is that the signal emitter does not know what is connected to it, or how many connections there are. If there are two connected slots, and they both try to modify the object that was passed by reference then you have all sorts of potential for bugs. It will work, in limited situations, with non-queued connections, but it's still bad design. – Dan Milburn Jun 13 '13 at 10:23
  • 2
    @Thibel You could just emit a signal in the main that passes the value as an argument to a slot in your thread every time you change the value of that variable. Also note, that you can't pass a non-const reference as an argument in signals and slots when using a queued connection. – thuga Jun 13 '13 at 11:02
  • @DanMilburn, I see your point about the misleading declaration. If it were desired to pass by reference, use of QMutex to prevent issues from multiple listeners modifying the data would protect from problems. This, however is academic because in QMetaObject::activate, if the connection type is AutoConnection and sender and receiver are in different threads, the value gets copied. See here: http://woboq.com/blog/how-qt-signals-slots-work.html – TheDarkKnight Jun 13 '13 at 12:50