2017-09-14 183 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