2017-04-27 14 views
0

はそれが可変長信号を作成し、スロットとして一般的なラムダを接続することは可能ですか?私のようなものを意味する(必要な場合たとえば、関与の機能のすべての定義が表示されている(例えば、インスタンス化のポイント)で):代わりに可変個引数信号と、一般的なラムダ

AUTOGEN: error: process for main.cpp:18: Error: Template function as signal or slot

moc failed...

ここでマクロSLOT()

#include <QCoreApplication> 
#include <QObject> 
#include <QTime> 

class A 
    : public QObject 
{ 
    Q_OBJECT 

public : 

    A(QObject * const parent = Q_NULLPTR) 
     : QObject{parent} 
    { ; } 

signals : 

    template< typename ...Ts > 
    void infoMessage(Ts... args); 

public slots : 

    void run() 
    { 
     emit infoMessage("Started at ", QTime::currentTime()); 
    } 

}; 

#include <QTimer> 
#include <QtDebug> 

#include "main.moc" 

int main(int argc, char * argv []) 
{ 
    QCoreApplication a{argc, argv}; 
    A a; 
    auto printInfoMessage = [&] (auto... args) 
    { 
     (qInfo() << ... << args); 
    }; 
    QObject::connect(&a, SIGNAL(infoMessage), printInfoMessage); 
    QTimer::singleShot(0, &a, &A::run); 
    return a.exec(); 
} 

現在はエラーメッセージを表示します&A::infoMessageの多くは役に立ちません。この制限を克服するための回避策はありますか?

回答の一部にstd::make_tuplestd::index_sequenceというものが含まれています。しかし、それほど冗長な解決策はありませんか?

答えて

1

テンプレートを持つための直接の回避策はありません。なぜなら、mocはすべてのシグナルとスロットを索引付けするからです。関数テンプレートは、一般にmocからアクセスできないコードに応じていくつかの関数を生成するので、これは関数テンプレートに対しては実行できません。

タプルで動作させることはできないと思いますが、これらもテンプレートです。

あなたの議論にQVariantおよび/またはQVariantListを使用することができます。また、あなたはあなたの意志でSIGNAL()SLOT()を置き換えることはできません、それはどちらかの信号である


エラーがQObject::connectラインによって引き起こされていないことに注意してくださいが、クラスAの信号宣言

またはスロットのいずれかにすることはできません。

そして最後に、あなたがこのフォームを使用してする必要があります。

QObject::connect(&a, &A::infoMessage, printInfoMessage); 

そしてprintInfoMessageオートパラメータを使用しているので、あなたがqOverloadを使用して自動解決を強制する必要があるかもしれません:

QObject::connect(&a, &A::infoMessage, qOverload<QVariantList>(printInfoMessage)); 
+0

はそれができません'emit someSignal(...);'にメンバー関数のインスタンス化のバリエーションをすべて集め、リンクする直前にすべての対応する特殊化を生成しますか? – Orient

+0

いいえ。「moc」は、コンパイルが完了する前に呼び出され、Q_OBJECTマクロを持つファイルのみを処理します。 mocの出力は、自分のC++ファイルがコンパイルされると同時にコンパイルされるC++コードです。したがって、リンク時間は、mocが任意の関数を追加するには遅すぎます。しかしリンク時間はあなたのテンプレート関数のユースケースを知るにはあまりにも早すぎます(例えばあなたがライブラリを構築していれば、あなたのライブラリを使うバイナリはあなたのテンプレートに基づいて関数を生成します) –

+0

あなたはどう思いますか?静的な反射が利用可能になったときにこれらの制限をすべて克服することは可能ですか?または、おそらく、ここで "clang"インフラストラクチャの一部が助けることができますか? – Orient

関連する問題