2017-09-14 181 views
2

我試圖簡化(即擺脫大量樣板代碼)創建必須標記爲「INVOKABLE」的類中的函數。使用宏創建Q_INVOKABLE函數

(非常像這樣的其他問題other question

要從小做起,我只是一個功能嘗試它:

#define CONCAT_NOEXPAND(A, B) A ## B 
#define CONCAT(A, B) CONCAT_NOEXPAND(A, B) 

#define HANDLER_PREFIX handler_ 
#define HANDLER_SIGNATURE (QString action, QString parameters) 

#define GENERATE_HANDLER_SIGNATURE(ACTION) CONCAT(HANDLER_PREFIX, ACTION) HANDLER_SIGNATURE 

#define GENERATE_HANDLERS(NAME) void GENERATE_HANDLER_SIGNATURE(NAME); 

class Test : public QObject 
{ 
    Q_OBJECT 

public: 
    explicit Test(QObject *parent = nullptr); 

private: 

    Q_INVOKABLE void handler_Test1 (QString, QString); // Ok 
    Q_INVOKABLE GENERATE_HANDLERS(Test2) // Error!! 
} 

使用宏GENERATE_HANDLERS產生這樣的錯誤:

  • 錯誤:粘貼「handler_」和「(」不提供有效的預處理令牌#define HANDLER_PREFIX handler_
  • 錯誤:在'void'之前預期的非限定id void GENERATE_HANDLER_SIGNATURE(NAME);

我也試着包括Q_INVOKABLE直接在MACRO GENERATE_HANDLERS,這導致在編譯代碼,但功能沒有被導出。

任何想法?

+0

您是否試圖擴展宏而無需編譯代碼在gnu編譯器中使用'-E'選項來查看真正發生了什麼? –

+0

是的。我嘗試過我的MACRO,他們[很棒](https://godbolt.org/g/5vXXMJ)。問題是,'Q_INVOKABLE'不能擴展我的MACRO – garlix

+0

@garlix我不知道如何檢查它,但我想Q_INVOKABLE宏先執行,執行它的工作,然後執行你的宏,他們不同意。 – Macias

回答

2

Q_INVOKABLE由元對象編譯器(moc)處理,它不擴展宏本身,並且在擴展宏之前運行,所以它看不到你的宏。

+0

這就是我猜測...所以沒有辦法避免樣板/複製和粘貼代碼? – garlix