如何使 clang-format 跳过 c++ 代码的部分

How to make clang-format skip sections of c++ code

有什么方法可以配置 clang-format 工具来跳过我的 Qt::connect 函数调用吗?我的构造函数中有几个连接,如下所示:

connect( m_Job, SIGNAL( error( const QString&, const QString& ) ),  this, SLOT( onError( const QString&, const QString& ) ) );
connect( m_Job, SIGNAL( message( const QString& ) ),                this, SLOT( onMessage( const QString& ) ) );
connect( m_Job, SIGNAL( progress( int, int ) ),                     this, SLOT( onProgress( int, int ) ) );

但在我 运行 格式化工具之后,它使它的可读性降低了:

connect( m_Job, SIGNAL( error(const QString&, const QString&)), this, SLOT( onError(const QString&, const QString&)) );
connect( m_Job, SIGNAL( message(const QString&)), this, SLOT( onMessage(const QString&)) );
connect( m_Job, SIGNAL( progress(int, int)), this, SLOT( onProgress(int, int)) );

您可以使用 new signal slot syntax 以获得更好的可读性。它看起来更简单

connect(sender, &Sender::valueChanged, receiver, &Receiver::updateValue);

使用 // clang-format off// clang-format on 使其跳过代码部分。

// clang-format off
// Don't touch this!
connect( m_Job, SIGNAL( error( const QString&, const QString& ) ),  this, SLOT( onError( const QString&, const QString& ) ) );
connect( m_Job, SIGNAL( message( const QString& ) ),                this, SLOT( onMessage( const QString& ) ) );
connect( m_Job, SIGNAL( progress( int, int ) ),                     this, SLOT( onProgress( int, int ) ) );
// clang-format on
// Carry on formatting

顺便说一句:您应该规范化 signal/slot 签名。因此,不需要引用和 const-references,Qt 中的签名规范化代码只是将它们删除。如果它是 this.

,您也不需要第三个参数

您的代码应如下所示:

connect(m_Job, SIGNAL(error(QString,QString)), SLOT(onError(QString,QString)));
connect(m_Job, SIGNAL(message(QString)), SLOT(onMessage(QString)));
connect(m_Job, SIGNAL(progress(int,int)), SLOT(onProgress(int,int)));

如果您坚持,参数类型之间肯定可以有空格,当然要付出一些运行时成本,因为规范化代码不再是 no-op。

您还可以利用 QMetaObject::connectSlotsByName 摆脱显式连接。这要求 m_Jobthis 的 child,并且有一个名字。例如:

class Foo : public Q_OBJECT {
  Job m_job;
  Q_SLOT void on_job_error(const QString&, const QString&);
  Q_SLOT void on_job_message(const QString&);
  Q_SLOT void on_job_progress(int, int);
public:
  Foo(QObject * parent = 0) :
    QObject(parent),
    m_job(this)
  {
    m_job.setObjectName("job");
    QMetaObject::connectSlotsByName(this);
  }
};

名称具有 on_name_signal 模式的插槽将由 connectSlotsByName 自动连接。 name 是发送者的名字 object,signal 是信号的名字。

最后,过多的空格会使您的代码更难阅读,而不是更容易阅读。这不是风格问题,而是简单的生理学问题。 Fovea centralis 的直径约为 2 angular 度。一 angular 度的视力大约是您一臂长度时拇指的宽度。阅读带有过多空格的代码需要更多 saccades/fixations 来沿着代码行重新定位您的中心视线。图 0.15-0.2s 需要处理每个注视的数据价值并将其与您正在阅读的代码的心智模型集成。都是可以衡量的。

作为轶事,而不是医学建议:如果鼻子上没有 +0.5 眼镜,我无法阅读密集的 sheet 音乐。我的视力在其他方面完全正常。 YMMV.