编译器选择错误的重载函数

时间:2018-04-16 11:51:31

标签: c++ qt signals-slots

我要将我的资源调整到Qt中的新信号和插槽语法。虽然下面列出的代码与已弃用的const char* signal参数运行良好,但它并不适用于新的QMetaMethod &signal语法。

class SignalWaiter : public QObject {
    Q_OBJECT
public:
    SignalWaiter(const QObject* sender, const QMetaMethod &signal);

private slots:
    void signalCaught();
};

SignalWaiter::SignalWaiter(const QObject* sender, const QMetaMethod &signal) {
    QObject::connect(sender, signal, this, &SignalWaiter::signalCaught);
}

void SignalWaiter::signalCaught() {
}

编译器在connect()命令处停止,并显示以下消息:

  

错误:C2664:' QMetaObject :: Connection QObject :: connect(const QObject *,const char *,const char *,Qt :: ConnectionType)const':无法转换参数2来自&#39 ; const QMetaMethod' to' const char *'

  

没有可用于执行此转换的用户定义转换运算符,或者无法调用运算符

很明显,编译器尝试使用旧语法调用重载的connect方法。我做错了什么?

3 个答案:

答案 0 :(得分:5)

connect() you're trying to use有签名:

QMetaObject::Connection QObject::connect(
    const QObject *sender, 
    const QMetaMethod &signal,
    const QObject *receiver,
    const QMetaMethod &method,
    Qt::ConnectionType type = Qt::AutoConnection)

请注意4 th 参数const QMetaMethod &method,它不是指向成员的指针,这就是您收到错误的原因。

要进行适当的转换,您可以使用:

auto metaSlot = metaObject()->method(metaObject()->indexOfSlot("signalCaught()"));
QObject::connect(sender, signal, this, metaSlot);

尽管如@ p-a-o-l-o所指出的,新的信号/槽语法使用指向成员函数的指针,而不是QMetaMethod。他的解决方案可能就是你真正想要的。

答案 1 :(得分:3)

我认为 O'Neil 的答案解决了编译问题,但如果OP真的想要

  

使我的信号源适应新的信号和插槽语法

也许他们想给SignalWaiter类另一个构造函数,就像这样:

template<typename T>
SignalWaiter(const T* sender, void (T::* signal)())
{
    QObject::connect(sender, signal, this, &SignalWaiter::signalCaught);
}

MyClass课程带有void mysignal()信号:

MyClass * myclass = new MyClass();
SignalWaiter * waiter = new SignalWaiter(myclass, &MyClass::mysignal);

答案 2 :(得分:0)

更改

QObject::connect(sender, signal, this, &SignalWaiter::signalCaught);

QObject::connect(sender, signal, this, QMetaMethod::fromSignal(&SignalWaiter::signalCaught));

对我有用,这与O'Neil的答案类似,但语法方面略短。请注意,您还需要在QMetaMethod::fromSignal()命令中的每个构造函数调用中包装signal参数。

p-a-o-l-o提出的解决方案对我不起作用,因为我的SignalWaiter类实际上继承自QObject,后者禁止使用模板。